objective-c - Objective C 中的 RLMRealm 数据库如何从 25Mb 增长到 11Gb?

标签 objective-c macos realm osx-elcapitan

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

Realm 作为 CocoaPod 加载,一切正常,我能够运行查询等,启动没有问题,但有些东西让我觉得我可能没有正确关闭我的调用?

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

在第一次运行时,或者如果我完全删除该 Realm ,那么我们将从头开始,一切都会飞快地进行。在下一次运行中,我的查询似乎运行得更慢,数据库首先从 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];
     }];
}

史蒂夫。

最佳答案

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

You should expect a Realm database to take less space on disk than an equivalent SQLite database. If your Realm file is much larger than you expect, it may be because you have a RLMRealm that is referring to an older version of the data in the database.

In order to give you a consistent view of your data, Realm only updates the active version accessed at the start of a run loop iteration. This means that if you read some data from the Realm and then block the thread on a long-running operation while writing to the Realm on other threads, the version is never updated and Realm has to hold on to intermediate versions of the data which you may not actually need, resulting in the file size growing with each write. The extra space will eventually be reused by future writes, or may be compacted — for example by calling writeCopyToPath:error:.

To avoid this issue you, may call invalidate to tell Realm that you no longer need any of the objects that you've read from the Realm so far, which frees us from tracking intermediate versions of those objects. The Realm will update to the latest version the next time it is accessed.

You may also see this problem when accessing Realm using Grand Central Dispatch. This can happen when a Realm ends up in a dispatch queue's autorelease pool as those pools may not be drained for some time after executing your code. The intermediate versions of data in the Realm file cannot be reused until the RLMRealm object is deallocated. To avoid this issue, you should use an explicit autorelease pool when accessing a Realm from a dispatch queue.

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

关于objective-c - Objective C 中的 RLMRealm 数据库如何从 25Mb 增长到 11Gb?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31589504/

相关文章:

c++ - 为什么我无法编译这个简单的线程测试?

ios - 在 Realm 中存储时区信息的最有效方法是什么?

ios - Realm on Swift - 创建关系

ios - 为什么在 IOS 中单击按钮时 View 不显示?

objective-c - NSStackView 只显示最新的自定义 View

objective-c - 检测全屏菜单栏移动

ios - Realm实例创建失败如何处理?

objective-c - SFAuthorizationPluginView 示例 NameAndPassword 在按下按钮后挂起

objective-c - 如何通过从 NSTableView 中选择一行来创建操作

c - 段错误: 11 on mac but not on linux while creating an array in C