ios app最大内存预算

问题描述 投票:138回答:8

我正在开发一款至少以3g为目标的ios游戏。我们正在将高清资产用于视网膜显示设备(iphone 4,ipod touch 4th gen)。

记忆方面,Ipod Touch 4th gen似乎是我们最受约束的设备,因为它具有与3gs相同的RAM(256与Iphone 4的512相比),但我们正在使用HD资产。该应用程序曾经在尝试加载100-110mb的ram时崩溃,但现在我们已经降到70MB,我们从来没有加载崩溃。

经过大量的搜索后,似乎没有官方的硬限制,那么我们应该如何知道要使用什么内存预算才能安全?我们希望能够为艺术家提供他们可以使用的预算,而不必担心每张地图的内存问题。

iphone ios memory memory-management
8个回答
38
投票

我想你已经回答了自己的问题:尽量不要超过70 Mb的限制,但它真的取决于很多东西:你正在使用的iOS版本(不是SDK),在后台运行的应用程序数量,内存的确切内存你正在使用等

只需避免即时内存飞溅(例如,你使用40 Mb的RAM,然后为一些简短的计算分配80 Mb的更多)。在这种情况下,iOS会立即终止您的应用程序。

您还应该考虑延迟加载资产(仅在您真正需要时才加载它们,而不是事先加载它们)。


391
投票

使用实用程序Split编写的测试结果(链接在他的回答中):

设备:(崩溃量/总量/总量百分比)

  • iPad1:127MB / 256MB / 49%
  • iPad2:275MB / 512MB / 53%
  • iPad3:645MB / 1024MB / 62%
  • iPad4:585MB / 1024MB / 57%(iOS 8.1)
  • iPad Mini第一代:297MB / 512MB / 58%
  • iPad Mini视网膜:696MB / 1024MB / 68%(iOS 7.1)
  • iPad Air:697MB / 1024MB / 68%
  • iPad Air 2:1383MB / 2048MB / 68%(iOS 10.2.1)
  • iPad Pro 9.7“:1395MB / 1971MB / 71%(iOS 10.0.2(14A456))
  • iPad Pro 10.5“:3057/4000 / 76%(iOS 11 beta4)
  • iPad Pro 12.9“(2015):3058/3999 / 76%(iOS 11.2.1)
  • iPad Pro 12。9“(2017):3057/3974 / 77%(iOS 11 beta4)
  • iPad Pro 11.0“(2018):2858/3769/76%(iOS 12.1)
  • iPad Pro 12.9“(2018,1TB):4598/5650 / 81%(iOS 12.1)
  • iPod touch第四代:130MB / 256MB / 51%(iOS 6.1.1)
  • iPod touch第五代:286MB / 512MB / 56%(iOS 7.0)
  • iPhone4:325MB / 512MB / 63%
  • iPhone4s:286MB / 512MB / 56%
  • iPhone5:645MB / 1024MB / 62%
  • iPhone5s:646MB / 1024MB / 63%
  • iPhone6:645MB / 1024MB / 62%(iOS 8.x)
  • iPhone6 +:645MB / 1024MB / 62%(iOS 8.x)
  • iPhone6s:1396MB / 2048MB / 68%(iOS 9.2)
  • iPhone6s +:1392MB / 2048MB / 68%(iOS 10.2.1)
  • iPhoneSE:1395MB / 2048MB / 69%(iOS 9.3)
  • iPhone7:1395 / 2048MB / 68%(iOS 10.2)
  • iPhone7 +:2040MB / 3072MB / 66%(iOS 10.2.1)
  • iPhone8:1364 / 1990MB / 70%(iOS 12.1)
  • iPhone X:1392/2785/50%(iOS 11.2.1)
  • iPhone XS:2040/3754 / 54%(iOS 12.1)
  • iPhone XS Max:2039/3735/55%(iOS 12.1)
  • iPhone XR:1792/2813 / 63%(iOS 12.1)

130
投票

我创建了一个小实用程序,它试图分配尽可能多的内存来崩溃,并记录发生内存警告和崩溃的时间。这有助于找出任何iOS设备的内存预算。

https://github.com/Split82/iOSMemoryBudgetTest


17
投票

在我的应用程序中,如果使用更多内存,用户体验会更好,所以我必须决定是否真的应该释放didReceiveMemoryWarning中的所有内存。基于Split和Jasper Pol的答案,使用最多45%的设备总内存似乎是一个安全的门槛(谢谢你们)。

如果有人想看看我的实际实现:

#import "mach/mach.h"

- (void)didReceiveMemoryWarning
{
    // Remember to call super
    [super didReceiveMemoryWarning];

    // If we are using more than 45% of the memory, free even important resources,
    // because the app might be killed by the OS if we don't
    if ([self __getMemoryUsedPer1] > 0.45)
    {
        // Free important resources here
    }

    // Free regular unimportant resources always here
}

- (float)__getMemoryUsedPer1
{
    struct mach_task_basic_info info;
    mach_msg_type_number_t size = sizeof(info);
    kern_return_t kerr = task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&info, &size);
    if (kerr == KERN_SUCCESS)
    {
        float used_bytes = info.resident_size;
        float total_bytes = [NSProcessInfo processInfo].physicalMemory;
        //NSLog(@"Used: %f MB out of %f MB (%f%%)", used_bytes / 1024.0f / 1024.0f, total_bytes / 1024.0f / 1024.0f, used_bytes * 100.0f / total_bytes);
        return used_bytes / total_bytes;
    }
    return 1;
}

斯威夫特(基于this answer):

func __getMemoryUsedPer1() -> Float
{
    let MACH_TASK_BASIC_INFO_COUNT = (sizeof(mach_task_basic_info_data_t) / sizeof(natural_t))
    let name = mach_task_self_
    let flavor = task_flavor_t(MACH_TASK_BASIC_INFO)
    var size = mach_msg_type_number_t(MACH_TASK_BASIC_INFO_COUNT)
    var infoPointer = UnsafeMutablePointer<mach_task_basic_info>.alloc(1)
    let kerr = task_info(name, flavor, UnsafeMutablePointer(infoPointer), &size)
    let info = infoPointer.move()
    infoPointer.dealloc(1)
    if kerr == KERN_SUCCESS
    {
        var used_bytes: Float = Float(info.resident_size)
        var total_bytes: Float = Float(NSProcessInfo.processInfo().physicalMemory)
        println("Used: \(used_bytes / 1024.0 / 1024.0) MB out of \(total_bytes / 1024.0 / 1024.0) MB (\(used_bytes * 100.0 / total_bytes)%%)")
        return used_bytes / total_bytes
    }
    return 1
}

8
投票

通过分配SPLITS repo,我构建了一个来测试可以分配给Today's Extension的iOS内存

iOSMemoryBudgetTestForExtension

以下是我在iPhone 5s中获得的结果

内存警告10 MB

应用程序崩溃在12 MB

通过这种方式,Apple只允许任何扩展功能发挥其全部潜力。


7
投票

你应该从WWDC 2010 Session videos观看会话147。这是“iPhone OS上的高级性能优化,第2部分”。 关于内存优化有很多好建议。

一些提示是:

  • 使用嵌套的NSAutoReleasePools确保您的内存使用不会出现峰值。
  • 从大图像创建缩略图时使用CGImageSource
  • 回应低记忆警告。

4
投票
- (float)__getMemoryUsedPer1
{
    struct mach_task_basic_info info;
    mach_msg_type_number_t size = MACH_TASK_BASIC_INFO;
    kern_return_t kerr = task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&info, &size);
    if (kerr == KERN_SUCCESS)
    {
        float used_bytes = info.resident_size;
        float total_bytes = [NSProcessInfo processInfo].physicalMemory;
        //NSLog(@"Used: %f MB out of %f MB (%f%%)", used_bytes / 1024.0f / 1024.0f, total_bytes / 1024.0f / 1024.0f, used_bytes * 100.0f / total_bytes);
        return used_bytes / total_bytes;
    }
    return 1;
}

如果一个人将使用TASK_BASIC_INFO_COUNT而不是MACH_TASK_BASIC_INFO,你会得到

kerr == KERN_INVALID_ARGUMENT(4)


2
投票

我通过设备RAM对Jaspers列表进行排序创建了另一个列表(我使用Split的工具进行了自己的测试并修复了一些结果 - 检查我在Jaspers线程中的注释)。

设备RAM:崩溃的百分比范围

  • 256MB:49% - 51%
  • 512MB:53% - 63%
  • 1024MB:57% - 68%
  • 2048MB:68% - 69%
  • 3072 MB:i%
  • 4096MB:77%
  • 6144MB:81%

特别案例:

  • iPhone X(3072MB):50%
  • iPhone XS / XS Max(4096MB):55%
  • iPhone XR(3072MB):未经测试(请在评论中发布崩溃值)

设备RAM可以轻松读取:

[NSProcessInfo processInfo].physicalMemory

根据我的经验,1GB设备使用45%,2 / 3GB设备使用50%,4GB设备使用55%是安全的。 macOS的百分比可能会更大一些。

© www.soinside.com 2019 - 2024. All rights reserved.