CoreData 导入期间内存使用率较高
我正在尝试执行相当大的 CoreData 导入(大约 25,000 行),同时仍然保持相当低的内存占用。我已经阅读了有关有效导入数据的文档,并努力实现那里建议的所有内容(包括将我的 MOC 的 undoManager 设置为 nil)。
不幸的是,当运行以下代码时,我的应用程序内存使用量仍然攀升至 180MB 左右。完成后,无论最终的 NSAutoreleasePool 消耗调用如何,应用程序将保持在 180MB 左右。
通过 Allocations 运行应用程序显示 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];
}
}
I'm attempting to perform a fairly large CoreData import (around 25,000 rows) while still maintaining a fairly low memory footprint. I've read the documentation surrounding efficient importing of data and have endeavoured to implement everything suggested there (including setting things like my MOC's undoManager to nil).
Unfortunately, my applications memory usage still climbs to around 180MB when running the below code. Upon completion the application will sit at around the 180MB mark, regardless of the final NSAutoreleasePool drain call.
Running the application through Allocations shows that 95% of the memory usage is attributable to my [self.moc save:&error]
call. What am I doing wrong here?
- (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];
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
与其处理自动释放池,为什么不通过使用
NSManagedObject
的initWithEntity:insertIntoManagedObjectContext:
创建托管对象来显式管理它们的生命周期?您可以在修改对象的属性后安全地释放它们,因为托管对象上下文会保留新插入的对象 - 直到将其保存到持久存储中。另外,我应该提到我在您的代码中看到的几个问题:
正如上面提到的,您没有记录
save:
操作中的错误。您确实应该——这可能会突出一些(可能不相关的)问题。如果 save: 成功,您确实不需要调用
reset
。请参阅 核心数据指南中的此部分。Instead of dealing with auto-release pools, why not explicitly manage the life-cycle of your managed objects by creating them with
NSManagedObject
'sinitWithEntity:insertIntoManagedObjectContext:
? You can safely release them after modifying the object's properties since a managed object context retains a newly inserted object -- till its saved to the persistent store.Also, I should mention a couple of problems that I see with your code:
As someone mentioned above, you are not logging errors from the
save:
operation. You really should -- that may highlight some (possibly unrelated) problem.If save: is successful, you really should not need to call
reset
. See this section in the core data guide.