Realm: mmap () failed: unable to allocate memory size

I am using Realm 2.4.3 in a large iPad application for one of our clients.
In most cases, Realm performed very well, but now the number of records is increasing and there is a memory problem.

application

  • Deployment Goal: 10.0
  • BaseSDK: 10.2
  • IPad only
  • Kingdom 2.4.3
  • The application is designed to work offline, so we use Realm for local storage.
  • There are several methods that synchronize data from Backend via HTTP to the Realm database and vice versa.
  • Number of records in Realm Database Number of records

(unexpected) behavior

  • file size in an area above 2.5 GB (with compact fix below ~ 500 KB)
  • realm tries to load the entire file into memory
  • IPad Air 2 (2 GB) crashes on iPad Pro (4 GB) works well

Problems i have already read

The fix I tried

compact hack writeCopyToURL:encryptionKey:error:

I have a Singleton object that processes all storage operations in an area that has a writeTransaction: method that processes beginWriteTransaction and commitWriteTransaction . All repository actions go through this method.

 - (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]; } } 

The fix works in storage! The file is compressed from 2.5 to 500 KB. But I still have a problem that the area wants to allocate too much memory:

 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} 

Is there anyone with an idea to fix this? :-)
If I missed any necessary information, leave a comment. I’ve been in this matter for several days, and my brain is like πŸ’₯

+5
source share

Source: https://habr.com/ru/post/1264870/


All Articles