【问题标题】:High memory usage during CoreData importCoreData 导入期间内存使用率高
【发布时间】:2011-03-28 08:12:36
【问题描述】:

我正在尝试执行相当大的 CoreData 导入(大约 25,000 行),同时仍然保持相当低的内存占用。我已阅读有关有效导入数据的文档,并努力实现那里建议的所有内容(包括将我的 MOC 的 undoManager 设置为 nil)。

不幸的是,运行以下代码时,我的应用程序内存使用量仍然攀升至 180MB 左右。完成后,无论最终的 NSAutoreleasePool 耗尽调用如何,应用程序都将位于 180MB 左右。

通过分配运行应用程序显示 95% 的内存使用可归因于我的 [self.moc save:&error] 调用。我在这里做错了什么?

- (void)generateCache
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSUInteger count = 0, batchSize = 1000;

    // SNIP SNIP

    // Iterate over our directory structure
    for(NSString *item in directoryStructure)
    {
        NSDictionary *info = [fm attributesOfItemAtPath:item error:nil];

        FileRecord *record = (FileRecord *)[NSEntityDescription insertNewObjectForEntityForName:@"FileRecord" inManagedObjectContext:self.moc];
        record.size = [NSNumber numberWithUnsignedLongLong:[info fileSize]];
        record.path = item;

        count ++;
        if(count == batchSize)
        {
            NSError *error = nil;

            if([self.moc save:&error])
            {
                NSLog(@"MOC saved down and reset");
                [self.moc reset];
                [pool drain];

                pool = [[NSAutoreleasePool alloc] init];
                count = 0;
            }
        }
    }

    // Perform any necessary last minute MOC saves
    if (count != 0) {
        [self.moc save:nil];
        [self.moc reset];
    }

    // Drain our NSAutoreleasePool
    [pool drain];

    // Tell our main thread that we're done
    if ([self respondsToSelector:@selector(completedCache)]) 
    {
        [self performSelectorOnMainThread:@selector(completedCache) withObject:nil waitUntilDone:NO];
    }
}

【问题讨论】:

  • 您没有记录保存生成的任何错误吗?另外,MOC 是否仅由导入使用?

标签: cocoa core-data import nsautoreleasepool


【解决方案1】:

为什么不使用NSManagedObjectinitWithEntity:insertIntoManagedObjectContext: 创建托管对象来明确管理托管对象的生命周期,而不是处理自动释放池?您可以在修改对象的属性后安全地释放它们,因为托管对象上下文会保留一个新插入的对象——直到它保存到持久存储中。

另外,我应该提一下我在您的代码中看到的几个问题:

  1. 正如上面提到的,您没有记录来自save: 操作的错误。你真的应该——这可能会突出一些(可能不相关的)问题。

  2. 如果 save: 成功,你真的不需要调用reset。请参阅核心数据指南中的this section

【讨论】:

  • 他在那个方法中有一个池。不会释放任何设置为自动释放的对象吗?
  • 是的,它会,但只有在每个 batchSize 对象被迭代之后。我的观点实际上是消除自动释放对象的(轻微的)额外复杂性,即使这不能解决问题,至少我们最终会得到更简单的代码,并且更容易调试。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-24
  • 2012-05-31
  • 1970-01-01
  • 2011-03-31
  • 1970-01-01
  • 1970-01-01
  • 2011-09-19
相关资源
最近更新 更多