简体   繁体   English

iPhone:低内存崩溃

[英]iPhone: Low memory crash

Once again I'm hunting memory leaks and other crazy mistakes in my code. 我再次在代码中寻找内存泄漏和其他疯狂的错误。 :) :)

I have a cache with frequently used files (images, data records etc. with a TTL of about one week and a size limited cache (100MB)). 我有一个经常使用的文件(图像,数据记录等,具有大约一周的TTL和大小受限制的缓存(100MB))的缓存。 There are sometimes more then 15000 files in a directory. 有时目录中有15000个以上的文件。 On application exit the cache writes an control file with the current cache size along with other useful information. 在应用程序退出时,缓存将写入具有当前缓存大小以及其他有用信息的控制文件。 If the applications crashes for some reason (sh.. happens sometimes) I have in such case to calculate the size of all files on application start to make sure I know the cache size. 如果应用程序由于某种原因崩溃(有时会发生崩溃),我必须在这种情况下计算应用程序启动时所有文件的大小,以确保我知道缓存的大小。 My app crashes at this point because of low memory and I have no clue why. 由于内存不足,我的应用此时崩溃了,我不知道为什么。

Memory leak detector does not show any leaks at all. 内存泄漏检测器根本不显示任何泄漏。 I do not see any too. 我也没有看到。 What's wrong with the code below? 下面的代码有什么问题? Is there any other fast way to calculate the total size of all files within a directory on iPhone? 还有其他快速方法可以计算iPhone上目录中所有文件的总大小吗? Maybe without to enumerate the whole contents of the directory? 也许无需枚举目录的全部内容? The code is executed on the main thread. 该代码在主线程上执行。

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;

Thanks, MacTouch 谢谢,MacTouch

Draining the pool "releases" it, it doesn't just empty it. 排空池会“释放”它,而不仅仅是将其清空。 Think of autorelease pools as stacks, so you have popped yours, meaning that all these new objects are going into the main autorelease pool and not being cleaned up until it gets popped. 将自动释放池视为堆栈,因此您已经弹出了堆栈,这意味着所有这些新对象都将进入主自动释放池,并且在弹出之前不会被清理。 Instead, move the creation of your autorelease pool to inside the loop. 而是将自动释放池的创建移到循环内部。 You can do something like 你可以做类似的事情

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM