0

所以应用程序崩溃了,没有堆栈跟踪或任何异常,我每次都可以复制这个崩溃。我的第一个想法是它必须是双重发布,在运行僵尸10分钟后,我无法让应用程序崩溃,甚至一次都没有。

查看 Allocations 后,我注意到在调用该方法时分配的对象的大小发生了巨大的跳跃。所以我最终在 for 循环中有一个 @autoreleasePool 。这个自动释放池修复了崩溃;但是我如何确认这确实是内存不足的问题?(didRecieveMemoryWarning 在崩溃前的任何时候都没有被调用)

为什么 autoreleasePool 解决了这个问题?

为什么没有调用 didRecieveMemoryWarning?是不是因为在我们到达当前运行循环结束之前应用程序内存不足?

- (void)doSomething
{

   for (Item *item in self.items)
   {
      @autoreleasepool
      {
         // A bunch of initializations here that take a lot of memory
      }
   }

}
4

3 回答 3

4

使用 Instruments 监控分配,看看它是否在没有自动释放池的情况下上升。

如果崩溃发生得特别快,或者您正在阻塞发生内存通知的队列,您将看不到通知。

Autorelease 最有可能解决了这个问题,因为在你的初始化过程中创建了大量的 autoreleased 对象。在退出循环之前,池不会被排干。

于 2012-08-20T19:43:19.920 回答
0

didRecieveMemoryWarning 不是异步调用的,您的主线程必须返回到 NSRunLoop 才能获取下一个事件,该事件可能是对 didRecieveMemoryWarning 的调用。此外,即使是你也无法清理自动释放池中的所有对象,所以如果问题是很多自动释放池的东西,你能否做很多事情是值得怀疑的。

于 2012-08-21T04:19:35.957 回答
-1

这是否在 UIApplicationMain 的同一线程上运行?for 范围是否使用 alloc/init 分配大量对象?ARC 是否启用?

@autorelease pool 是堆的一部分,负责在没有显式调用 init 的情况下分配对象,如 / [NSString stringWithFormat:"%@",format] / 或使用自动释放返回,如 / [[[NSObject alloc] init] autorelease] / .

问题一定已经消失了,因为每次循环结束时,它都会执行 [pool drain],释放该范围内所有静态分配的对象。我建议您创建另一个线程来执行此分配并在两者之间暂停主线程(也许使用 UIAlertView?)。当您在另一个自动释放池中创建一个自动释放池时,第二个可能会卡在第一个中,只会在应用程序结束时释放。希望能帮助到你。

于 2012-08-20T19:55:01.473 回答