IOS应用因低内存而被终止,但未收到内存警告。

7
我遇到了一个问题,已经有一段时间了,我想知道是否有人可以帮忙。 我正在开发一个IOS应用程序(iPad),使用主导航控制器和大量UIImage。 在使用应用程序一段时间后,应用程序因低内存而被杀死(不在特定视图中),但通过检查iPad日志,我并不总是看到低内存警告(有时是,有时不是)。 即使我收到了其中一个,它也只是“收到低内存警告”,但我从未收到“Level 1”或“Level 2”。 通过使用xCode的泄漏工具,我找不到任何泄漏。 有人可以帮忙吗?

你可能在某处请求了巨大的内存分配吗? - Hot Licks
我想过,但并不是真的... =/ - user1089658
如果我以不同的顺序访问我的视图控制器,它将在其他地方执行完全相同的操作。 - user1089658
我也有类似的问题。我怀疑我的问题是由于 UI 线程被阻塞了很长时间。你找到解决方案了吗? - arundevma
2个回答

10

内存警告会作为通知被发送,因此它会在运行循环中排队等待分配机会。如果你编写一个(故意破坏的)循环:

while(1)
{
    NSString *newString = [NSString string];
}

最终,您的应用程序可能由于内存不足而被终止,但是您从未有机会收到低内存警告。

如果您由于内存不足而被终止而没有收到警告,则很可能在某个地方创建了自己的内存瓶颈,可能存在一些使许多东西留在autorelease池中的循环 - 因此,如果您通过整个循环,则临时对象消失了,因此没有长期的印记,但是它们在您停留在循环中的所有时间内不断累积。

为避免这种情况,您需要查看将循环的内部部分嵌套在它们自己的NSAutoreleasePool中。 例如,此循环:

while(1)
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSString *newString = [NSString string];
    [pool drain]; // stylistically preferred to release, but equivalent
                  // in reference counted environments
}

这个程序将永远运行但不会触发低内存条件。


有什么建议可以识别内存不足导致死循环的代码块吗?我正在处理一个大型应用程序,它存在这个问题(没有内存警告,只是崩溃),而且它在很多地方都使用了大量的内存。由于苹果隐藏了所有图像/ CG / CALayer渲染,因此很难判断哪个是哪个 - 并且应用程序中有许多许多循环。除了在应用程序中放置NSAutoReleasePools之外,自动/主动缩小它们的范围是否有其他建议? - Adam

5

您还可以尝试查找内存泄漏。苹果的Xcode开发环境提供了一个内存泄漏检测工具,最简单的方法是直接从Xcode中运行它:

Xcode: 1. 选择Product; 2. 启动性能工具(Profiler); 3. 在Instrument中选择Leak。

这个工具非常擅长检测内存泄漏,并且易于使用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接