gpt4 book ai didi

ios - Realm :mmap() 失败:无法分配内存大小

转载 作者:可可西里 更新时间:2023-11-01 03:58:47 24 4
gpt4 key购买 nike

我正在为我们的一位客户在大型 iPad 应用程序中使用 Realm 2.4.3
大多数时候 Realm 表现得很好,但现在 Records 的数量在增加并且出现一些内存问题。

应用

  • 部署目标:10.0
  • BaseSDK:10.2
  • 仅限 iPad
  • Realm 2.4.3
  • 该应用程序专为离线工作而设计,这就是我们使用 Realm 进行本地存储的原因
  • 有一些方法可以通过 HTTP 将数据从后端同步到 Realm 数据库,反之亦然。
  • Realm 数据库 Number of Records 中的记录数

(意外)行为

  • realm 文件大小增长超过 2.5GB(压缩修复低于 ~500KB)
  • realm 尝试将整个文件加载到内存中
  • iPad Air 2 (2GB) 崩溃,在 iPad Pro (4GB) 上一切正常

我已经读过的问题

我尝试过的修复

writeCopyToURL:encryptionKey:error: 紧凑黑客

我有一个单例对象,它处理所有存储到 Realm 的操作,它有一个 writeTransaction: 方法来处理 beginWriteTransactioncommitWriteTransaction 处理。所有存储操作都通过此方法进行。

- (void)writeTransaction:(void (^)(void))block
{
[self _ensureRealmThread:^{
NSDate *startDate = [NSDate date];
[[self _defaultRealm] beginWriteTransaction];
block();

NSError *commitWriteTransactionError = nil;
[[self _defaultRealm] commitWriteTransaction:&commitWriteTransactionError];

if (commitWriteTransactionError) {
NSLog(@"commit error: %@", commitWriteTransactionError);
}

NSTimeInterval time = [[NSDate date] timeIntervalSinceDate:startDate];
if (time > 0.5) {
NSLog(@"WARNING: Transaction duration > 0.5");
}

// i added these 5 lines to compact the database every 2000 requests
_writeTransactionIndex++;
if (_writeTransactionIndex > 2000) {
_writeTransactionIndex = 0;
[self compactDatabase];
}
}];
}


- (void)compactDatabase
{
NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask,
YES);
NSString *documentsPath = searchPaths[0];

NSString *defaultCompactPath = [documentsPath stringByAppendingPathComponent:@"defaultCompact.realm"];
NSURL *defaultCompactURL = [NSURL fileURLWithPath:defaultCompactPath];

// remove old
if ([[NSFileManager defaultManager] fileExistsAtPath:[defaultCompactURL path]]) {
[[NSFileManager defaultManager] removeItemAtURL:defaultCompactURL
error:nil];
}

NSError *writeError = nil;
[[self _defaultRealm] writeCopyToURL:defaultCompactURL
encryptionKey:nil
error:&writeError];
if (!writeError) {
[[NSFileManager defaultManager] replaceItemAtURL:[self _defaultRealm].configuration.fileURL
withItemAtURL:defaultCompactURL
backupItemName:nil
options:NSFileManagerItemReplacementUsingNewMetadataOnly
resultingItemURL:nil
error:nil];
}
}

修复在存储中有效!!该文件从 2.5GB 缩小到 500KB。但是我仍然遇到 Realm 想要分配太多内存的问题:

commit error: Error Domain=io.realm Code=9 "mmap() failed: Cannot allocate memory size: 268435456 offset: 2952790016" UserInfo={NSLocalizedDescription=mmap() failed: Cannot allocate memory size: 268435456 offset: 2952790016, Error Code=9}

有人有办法解决这个问题吗? :-)
如果我错过了一些必要的信息,请发表评论。我在这个问题上已经好几天了,我的大脑就像💥

最佳答案

我们遇到了这个错误。在 Realm 解决问题之前,以下是我们的解决方法:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_SERIAL, 0), ^{

RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
config.schemaVersion = [schema intValue];
config.shouldCompactOnLaunch = ^BOOL(NSUInteger totalBytes, NSUInteger usedBytes){
// totalBytes refers to the size of the file on disk in bytes (data + free space)
// usedBytes refers to the number of bytes used by data in the file

// Compact if the file is over 50MB in size and less than 50% 'used'
NSUInteger oneHundredMB = 50 * 1024 * 1024;
return (totalBytes > oneHundredMB) && (usedBytes / totalBytes) < 0.5;
};

__block BOOL deleteRealm = false;

//schema has changed. Set delete flag.
config.migrationBlock = ^(RLMMigration *migration, uint64_t oldSchemaVersion) {
if (oldSchemaVersion < [schema intValue]) {
deleteRealm = TRUE;
}
};

[RLMRealmConfiguration setDefaultConfiguration:config];


//*** Memory Allocation bug 'fix/hack' ***
// Put realm init in try block. If it fails, blow it away in catch block. Then the following realm init will work.
// This fix eliminated the error for us, with no effect on perfomance.
@try
{
[RLMRealm defaultRealm];
}
@catch(...) {
NSURL *rurl = [RLMRealmConfiguration defaultConfiguration].fileURL;
// blow the database clean
NSError *error = nil;
[[NSFileManager defaultManager] removeItemAtURL:rurl error:&error];
if(error) {
NSLog(@"error %@ removing realm db", error);
} else {
NSLog(@"removed realm db successfully!");
}
}

[RLMRealm defaultRealm];

if (deleteRealm){
[[RLMRealm defaultRealm] beginWriteTransaction];
[[RLMRealm defaultRealm] deleteAllObjects];
[[RLMRealm defaultRealm] commitWriteTransaction];
deleteRealm = FALSE;
}
});

关于ios - Realm :mmap() 失败:无法分配内存大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42527836/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com