iOS应用程序最大内存预算

我正在开发一款以3gs为目标的ios游戏。 我们正在使用高清素材视网膜显示设备(iPhone 4,iPod touch第四代)。

内存方面,Ipod Touch 4th gen似乎是我们最受限制的设备,因为它具有与3gs相同数量的内存(256比Iphone 4的512),但我们正在使用HD资源。 当试图加载100-110mb的内存时,该应用程序崩溃,但现在我们已经降到70MB,我们从来没有加载过程中崩溃。

经过大量的search,似乎没有官方的硬性限制,那么我们应该如何去了解使用什么内存预算来保证安全呢? 我们希望能够给艺术家一个预算,他们可以使用,而不用担心每个地图的内存。

我想你已经回答了你自己的问题:尽量不要超越70 Mb的限制,但是这取决于很多事情:你使用的是什么版本的iOS(不是SDK),有多less应用程序在后台运行,具体的内存你正在使用等

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

你也应该考虑延迟加载资源(只在你真正需要而不是预先加载时才加载)。

用公用事业Splittesting的结果写道(链接在他的答案中):

设备:(碰撞量/总量/总量的百分比)

  • iPad1:127MB / 256MB / 49%
  • iPad2:275MB / 512MB / 53%
  • iPad3:645MB / 1024MB / 62%
  • iPad4:585MB / 1024MB / 57%(iOS 8.1)
  • iPad迷你第一代: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“(2017):3057/3974/77%(iOS 11 beta4)
  • 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%(iOS9.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)

我创build了一个小实用程序,它尝试尽可能多地分配内存来崩溃,并logging内存警告和崩溃发生的时间。 这有助于找出什么是iOS设备的内存预算。

https://github.com/Split82/iOSMemoryBudgetTest

在我的应用程序中,如果使用更多的内存,用户体验会更好,所以我必须决定是否应该释放所有可以在didReceiveMemoryWarning的内存。 基于斯普利特和贾斯珀波尔的答案,使用最多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; } 

Swift(基于这个答案 ):

 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 } 

您应该观看WWDC 2010会话video中的会话147。 这是“iPhone OS上的高级性能优化,第2部分”。
内存优化有很多好的build议。

一些提示是:

  • 使用嵌套NSAutoReleasePool来确保你的内存使用不会激增。
  • 从大图像创build缩略图时使用CGImageSource
  • 回应低内存警告。

通过分叉SPLITS回购,我build立了一个testing可以分配给今日分机的iOS内存

iOSMemoryBudgetTestForExtension

以下是我得到iPhone 5s的结果

内存警告在10 MB

应用程序崩溃在12 MB

通过这种方式,苹果公司只允许任何扩展工作,充分发挥其潜力

 - (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)

我通过设备RAM对Jaspers列表进行sorting创build了另一个列表(我使用Split的工具进行了自己的testing并修复了一些结果 – 请参阅本主题中的注释)。

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

  • 256MB:49% – 51%
  • 512MB:53% – 63%
  • 1024MB:57% – 68%
  • 2048MB:68% – 69%
  • 3072MB:66%
  • 4096MB:77%

设备RAM可以被轻松读取:

 [NSProcessInfo processInfo].physicalMemory 

从我的经验来看,1GB设备使用率为45%,2 / 3GB设备使用率为50%,4GB设备使用率为55%。 macOS的百分比可能会更大一些。