【问题标题】:How can a RLMRealm database grow from 25Mb to 11Gb in Objective C?在 Objective C 中,RLMRealm 数据库如何从 25Mb 增长到 11Gb?
【发布时间】:2015-07-23 13:54:45
【问题描述】:

我在我的一个项目中使用了 Realm.io,我已经在几个 iOS 项目中使用过它,但这是我第一个使用它的 Objective C 桌面应用程序,所以这个问题是基于操作系统的X 用法。在继续之前,我认为还值得一提的是测试机器正在运行 El Capitan,所以我知道这是测试版软件。

Realm 作为 CocoaPod 加载,一切正常,我可以运行查询等,启动没有问题或其他任何事情让我觉得我可能没有正确关闭呼叫?

我的对象有两种主要的不同类型,一种用于保存“组”,另一种用于保存实际的“对象”。该应用程序是一个照片上传器,因此它会读取 Apple 的照片应用程序,索引所有媒体对象和组,然后上传它们。

在第一次运行时,或者如果我完全删除了领域,所以我们从头开始,一切都会飞快地进行。在下一次运行中,我的查询似乎运行得更慢了,数据库首先从 25Mb 变为 50Mb,然后在一个小时后我再次检查时,我在 11Gb 左右。

我对 Realm 的主要用途是在单例中,但我正在执行一个后台队列,该队列正在为每个对象排队一个新作业,因此当它发现一张照片时,它会排队另一个作业以检查它是否存在于数据库中,如果不存在创建它,如果它更新任何现有信息。因为它这样做,除非我在作业中声明 Realm,否则我会遇到线程错误,因此每次都定义它。

下面是我的一个电话示例,任何人都可以提出一些我可能做错的事情,或者现在有什么办法可以控制或压缩数据库的大小吗?

- (void)saveMediaObject:(MLMediaObject *)mediaObject mediaGroup:(MLMediaGroup *)mediaGroup
{
    [jobQueue addOperationWithBlock:
     ^{
         NSLog(@"saveMediaObject");

         lastScanResult = [NSDate date];

         RLMRealm *realm = [RLMRealm defaultRealm];

         SPMediaObject *spMediaObject = [SPMediaObject objectInRealm:realm forPrimaryKey:[mediaObject identifier]];

         if(spMediaObject == nil)
         {
             spMediaObject = [[SPMediaObject alloc] init];
             spMediaObject.identifier = [mediaObject identifier];
         }

         [realm beginWriteTransaction];

         spMediaObject.lastSeen = [NSDate date];
         spMediaObject.versionURL = [[mediaObject URL] path];
         spMediaObject.versionMimeType = [self mimeTypeForExtension:[[spMediaObject.versionURL pathExtension] lowercaseString]];
         spMediaObject.originalURL = [[mediaObject originalURL] path];
         spMediaObject.originalMimeType = [self mimeTypeForExtension:[[spMediaObject.originalURL pathExtension] lowercaseString]];

         if([mediaObject name] != nil)
         {
             spMediaObject.caption = [mediaObject name];
         }
         else
         {
             spMediaObject.caption = @"";
         }

         [realm addOrUpdateObject:spMediaObject];

         [realm commitWriteTransaction];
     }];
}

史蒂夫。

【问题讨论】:

    标签: objective-c macos realm osx-elcapitan


    【解决方案1】:

    Realm's docs on file size 应该提供一些关于这里发生的事情以及如何缓解问题的见解:

    您应该期望 Realm 数据库占用的磁盘空间比同等数据库少 SQLite 数据库。如果您的 Realm 文件比您预期的要大得多,可能是因为 你有一个RLMRealm 那是 引用数据库中旧版本的数据。

    为了给您提供一致的数据视图,Realm 仅更新 在运行循环迭代开始时访问的活动版本。这意味着如果 您从 Realm 读取一些数据,然后在长时间运行时阻塞线程 在其他线程上写入领域时操作,版本永远不会 已更新,Realm 必须保留您的数据的中间版本 可能实际上不需要,导致文件大小随着每次写入而增长。 额外的空间最终将被未来的写入重用,或者可能被压缩 — 例如通过调用writeCopyToPath:error:

    为避免此问题,您可以致电invalidate 告诉 Realm 你不再需要到目前为止从 Realm 读取的任何对象, 这使我们无需跟踪这些对象的中间版本。领域将更新为 下次访问时最新版本。

    在使用 Grand Central Dispatch 访问 Realm 时,您也可能会看到此问题。 当 Realm 最终进入调度队列的自动释放池时,可能会发生这种情况 执行代码后,这些池可能在一段时间内不会耗尽。中间体 Realm 文件中的数据版本不能重复使用,直到 RLMRealm 对象被释放。 为避免此问题,您应在访问 Realm 时使用显式自动释放池 来自调度队列。

    如果这些建议没有帮助,Realm 工程团队将很乐意对您的项目进行分析,以确定最小化文件大小增长的方法。您可以将代码私下发送至 help@realm.io。

    【讨论】:

    • 感谢您的回复。我已经浏览了文档并看到了这一点,并认为我正确地实现了它,但是自从发布以来,我发现一个代码块在不需要时保留在 Realm 上,因为上面的文字表明它正在增长在尺寸方面。我以为我拥有一切,但错过了一点。
    猜你喜欢
    • 2016-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-30
    • 1970-01-01
    • 1970-01-01
    • 2020-09-06
    • 1970-01-01
    相关资源
    最近更新 更多