【问题标题】:iPhone: Low memory crashiPhone:内存不足崩溃
【发布时间】:2010-05-08 15:12:39
【问题描述】:

我又一次在我的代码中寻找内存泄漏和其他疯狂的错误。 :)

我有一个包含常用文件(图像、数据记录等)的缓存,其 TTL 约为 一周和一个大小有限的缓存(100MB))。有时一个文件中有超过 15000 个文件 目录。在应用程序退出时,缓存会使用当前缓存写入控制文件 大小以及其他有用的信息。如果应用程序由于某种原因崩溃 (sh ..有时会发生)在这种情况下,我必须计算应用程序启动时所有文件的大小,以确保我知道缓存大小。 由于内存不足,我的应用程序此时崩溃,我不知道为什么。

内存泄漏检测器根本不显示任何泄漏。我也没有看到。怎么了 用下面的代码?有没有其他快速的方法来计算所有文件的总大小 在 iPhone 上的目录中?也许不用枚举目录的全部内容? 代码在主线程上执行。

NSUInteger result = 0;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSDirectoryEnumerator *dirEnum = [[[NSFileManager defaultManager] enumeratorAtPath:path] retain];
int i = 0;
while ([dirEnum nextObject]) {
   NSDictionary *attributes = [dirEnum fileAttributes];
   NSNumber* fileSize = [attributes objectForKey:NSFileSize];
   result += [fileSize unsignedIntValue];

   if (++i % 500 == 0) { // I tried lower values too   
      [pool drain];
   }
}
[dirEnum release];
dirEnum = nil;
[pool release];
pool = nil;

谢谢, MacTouch

【问题讨论】:

    标签: iphone memory-leaks crash


    【解决方案1】:

    排空池会“释放”它,而不仅仅是清空它。将自动释放池视为堆栈,因此您已经弹出了您的堆栈,这意味着所有这些新对象都将进入主自动释放池,并且在弹出之前不会被清理。相反,将自动释放池的创建移到循环内部。你可以做类似的事情

    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    int i = 0;
    while( shouldloop ) {
      // do stuff
      if( ++i%500 == 0 ) {
        [pool drain];
        pool = [[NSAutoreleasePool alloc] init];
      }
    }
    [pool drain];
    

    【讨论】:

    • 谢谢。嘘..我真的不知道。我一直认为流失只是为所有自动释放的对象提供免费的内存。这是 RTFM 的经典案例。 :-) 谢谢。现在我必须确保在所有使用 Autoreleasepool 的地方都以相同的方式执行此操作。呃……有很多。 :)
    • MacTouch:阅读 NSAutoReleasePool 的文档——Cocoa 和 Cocoa-touch 之间的行为存在重要差异。
    • 啊。 [pool drain] 发送释放消息。我明白了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-22
    • 1970-01-01
    • 1970-01-01
    • 2012-07-01
    • 2018-07-28
    相关资源
    最近更新 更多