ios - 核心数据导入 - 不释放内存

标签 ios objective-c core-data memory memory-management

我的问题是关于核心数据和内存没有被释放。我正在执行从返回 json 的 WebService 导入数据的同步过程。我在内存中加载数据以导入、循环并创建 NSManagedObjects。导入的数据需要创建与其他对象有关系的对象,总共有大约 11.000 个。但是为了隔离问题,我现在只创建第一级和第二级的项目,不考虑关系,那些是 9043 个对象。

我开始检查使用的内存量,因为应用程序在进程结束时崩溃(使用完整数据集)。第一次内存检查是在将 json 加载到内存中之后,以便测量真正仅考虑对象的创建和插入到 Core Data 中。我用来检查内存使用的是这个代码( source )

-(无效)get_free_memory {

struct task_basic_info 信息;
mach_msg_type_number_t size = sizeof(info);
kern_return_t kerr = task_info(mach_task_self(),
TASK_BASIC_INFO,
(task_info_t)&信息,
&大小);
如果(克尔 == KERN_SUCCESS){
NSLog(@"正在使用的内存(以字节为单位):%f",(float)(info.resident_size/1024.0)/1024.0);
}其他{
NSLog(@"task_info() 出错:%s", mach_error_string(kerr));
}
}

我的设置:

  • 1 名常驻店铺协调员
  • 1 Main ManagedObjectContext (MMC)(NSMainQueueConcurrencyType 用于读取(仅读取)应用程序中的数据)
  • 1 后台ManagedObjectContext(BMC)(NSPrivateQueueConcurrencyType,undoManager设置为nil,用于导入数据)

  • BMC 独立于 MMC,因此 BMC 不是 MMC 的子上下文。而且它们不共享任何父上下文。我不需要 BMC 来通知 MMC 的变化。所以BMC只需要创建/更新/删除数据。

    平台:
  • iPad 2 和 3
  • iOS,我已经测试将部署目标设置为 5.1 和 6.1。没有区别
  • XCode 4.6.2

  • 问题:
    导入数据,使用的内存不会停止增加,即使在过程结束后,iOS 似乎也无法耗尽内存。如果数据样本增加,则会导致内存警告和应用程序关闭后。

    研究:
  • 苹果文档
  • Efficiently importing Data
  • Reducing Memory Overhead
  • 将数据导入 Core Data 时要牢记的要点 ( Stackoverflow )
  • 已完成测试并分析内存释放。他似乎和我有同样的问题,他发送了一个 Apple Bug 报告,Apple 尚未回复。 ( Source )
  • 导入和显示大型数据集 ( Source )
  • 表示导入大量数据的最佳方式。虽然他提到:

    "I can import millions of records in a stable 3MB of memory without calling -reset."



    这让我觉得这可能有什么可能? ( Source )

  • 测试:

    数据样本:共创建 9043 个对象。
  • 关闭关系的创建,因为文档说它们“昂贵”
  • 没有进行抓取

  • 代码:
    - (void)processItems { [self.context performBlock:^{ for (int i=0; i < [self.downloadedRecords count];) { @autoreleasepool { [self get_free_memory]; // prints current memory used for (NSUInteger j = 0; j < batchSize && i < [self.downloadedRecords count]; j++, i++) { NSDictionary *record = [self.downloadedRecords objectAtIndex:i]; Item *item=[self createItem]; objectsCount++; // fills in the item object with data from the record, no relationship creation is happening [self updateItem:item WithRecord:record]; // creates the subitems, fills them in with data from record, relationship creation is turned off [self processSubitemsWithItem:item AndRecord:record]; } // Context save is done before draining the autoreleasepool, as specified in research 5) [self.context save:nil]; // Faulting all the created items for (NSManagedObject *object in [self.context registeredObjects]) { [self.context refreshObject:object mergeChanges:NO]; } // Double tap the previous action by reseting the context [self.context reset]; } } }]; [self check_memory];// performs a repeated selector to [self get_free_memory] to view the memory after the sync }
    测量:

    它从 16.97 MB 增加到 30 MB,在同步后减少到 28 MB。每 5 秒重复一次 get_memory 调用可将内存保持在 28 MB。

    其他没有运气的测试:
  • 按照研究 2) 中的指示重新创建持久存储没有任何影响
  • 测试让线程稍等一下以查看内存是否恢复,示例 4)
  • 在整个过程之后将上下文设置为 nil
  • 完成整个过程而不在任何时候保存上下文(因此丢失信息)。这实际上导致保持较少的内存量,将其保留为 20 MB。但它仍然没有减少......我需要存储的信息:)

  • 也许我遗漏了一些东西,但我确实测试了很多,在遵循指导方针之后,我希望看到内存再次减少。我已经运行了分配工具来检查堆增长,这似乎也很好。也没有内存泄漏。

    我已经没有想法可以测试/调整了......如果有人能帮助我解决我可以测试的其他内容,或者指出我做错了什么,我将不胜感激。或者就是这样,它应该如何工作......我怀疑......

    感谢您的帮助。

    编辑

    我已经使用仪器使用事件监视器模板来分析内存使用情况,并且“实际内存使用情况”中显示的结果与控制台中打印的结果相同 get_free_memory并且内存似乎仍然永远不会被释放。

    最佳答案

    好吧,这很尴尬……在计划中启用了僵尸,在参数上它们被关闭,但在诊断中检查了“启用僵尸对象”……

    关闭此功能可保持内存稳定。

    感谢那些阅读问题并试图解决它的人!

    关于ios - 核心数据导入 - 不释放内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18537380/

    相关文章:

    ios - MSQuery includeTotalCount 不起作用?

    iphone - 使用Button Font Awesome 图标无法正确显示?而是显示怪异的图标

    ios - CLLocationManagerDelegate 委托(delegate)在 8.1 中未调用 iOS

    ios - 如何将 Int 显示到屏幕/标签 SWIFT

    iphone - 为什么我不必在第二个 TableViewController 中释放 ManagedObjectContext

    ios - for循环的返回字符串 - Swift 3

    ios - ReactiveCocoa 4 : How to send error to an observer without interrupting the signal

    ios - 使用导航 Controller 时如何跳过 2 个 View

    ios - CoreData : setAttribute has no effect 令人困惑的问题

    iOS CoreData NSPredicate 一次查询多个属性