为什么即使我释放大量内存以响应内存警告,iOS也会终止我的应用程序?

Ben*_*oyt 8 memory-management objective-c terminate ios sdwebimage

我无法弄清楚为什么iOS会因为内存使用而终止我的应用程序(iPad,iOS 4),即使在释放大量内存以响应低内存警告之后也是如此.例如,这是一个典型的终止方案,我经常记录内存使用情况 - 查看"app"用法,每行的第一个KB值:

...
2011-12-14 13:25:42.343 Oyster[211:707] Memory usage (KB): app 268256, delta 6472, used 366800/373940
2011-12-14 13:25:43.292 Oyster[211:707] Memory usage (KB): app 273900, delta 5644, used 372444/381024
2011-12-14 13:25:44.159 Oyster[211:707] Memory usage (KB): app 282920, delta 9020, used 381464/389116
2011-12-14 13:25:45.184 Oyster[211:707] Memory usage (KB): app 272140, delta -10780, used 370684/379432
2011-12-14 13:25:46.109 Oyster[211:707] Memory usage (KB): app 260412, delta -11728, used 358956/365900
2011-12-14 13:25:48.443 Oyster[211:707] Received memory warning. Level=2
2011-12-14 13:25:48.454 Oyster[211:707] Memory usage (KB): app 9172, delta -251240, used 107716/112548
(gdb)
Run Code Online (Sandbox Code Playgroud)

您可以看到应用内存使用量增加,直到收到内存警告.然后我正确响应内存警告并释放一堆(250MB!)的内存.此时我的应用程序终止,iOS进入iPad主屏幕.

此处的"内存使用情况"日志与我的logMemoryUsage()函数一起显示,该函数基于此答案的代码.

为了记录,我正在使用SDWebImage在内存中缓存UIImages,但如图所示,它通过清空其缓存来处理内存警告(此时相当大).我意识到我可以调整SDWebImage的缓存来填充所有可用内存并等待内存警告,但这引出了以下问题......

为什么iOS会终止我的应用程序,即使我通过愉快地释放大量内存来响应内存警告?

XJo*_*nes 11

这是对内存管理等良好实践的一般回答.通常,内存缓存之类的声音只是变得太大,即使它响应内存警告而释放对象,到那时为时已晚.

  1. 内存警告本质上并不"坏",你无法避免它们.它们是iOS生命周期的正常部分,您必须通过释放所有对象中的所有非必要数据来正确处理它们,以确保您的应用程序以负责任的方式运行.即使您的应用占用空间很小,您仍然可以获得有关设备上其他条件的内存警告(例如其他正在使用的应用程序等).我在UIApplicationDidReceiveMemoryWarningNotification这里指的是运行时通知.调试器消息(例如"已接收内存警告.级别= 2")特定于您的应用程序,但它们不一定与接收运行时通知相关.

  2. 我不太了解SDWebCache.我会看一下实现并确保它有效地释放内存.例如,@autoreleasepool在相关位置使用可能有助于它在运行循环中更有效地释放对象.

  3. 您应该努力使应用程序的内存占用尽可能地受到限制.可以使用内存缓存来处理图像数据,但我会限制它的大小.如果您的应用程序占用空间大于250MB,即使您处理内存警告,我也不会感到惊讶.到那时可能已经太晚了.

  4. 您可能有其他问题导致/促成终止.正如评论所建议的那样,您需要在仪器中进行更多调试以查找泄漏,访问不良等.在此处发布崩溃日志会很有帮助.


Pet*_*ese 1

如果没有更多信息,我不知道这些是否适用于您,但在尝试清理内存警告后,我通常会遇到某些问题:

\n\n
    \n
  • 未知的循环引用会阻止内存像您期望的那样被释放。使用仪器来寻找它们。我最近修复了一个案例,其中我不小心在块内使用 self ,导致保留。当出现内存警告时我们注意到了这一点,并且我们无法通过释放该资源来很好地从警告中恢复。
  • \n
  • 清理资源 \xe2\x80\x93 或自动释放资源 \xe2\x80\x93 已经释放了仍然需要的东西。你可能会在你不期望的地方得到一个零,或者你可能对僵尸进行操作。检查你的保留和清理工作,尤其是代表的清零。打开僵尸和异常断点。
  • \n
\n\n

通常,最好的解决方案是首先防止内存警告发生。

\n