AddressSpaceExhausted Cannot allocate memory size - iOS SDK

Hi Team,

Our iOS apps are crashing after some time. The app work in background syncing with Realm when necessary.

After some good hours of working, the app crash with this error log:

libc++abi: terminating with uncaught exception of type realm::AddressSpaceExhausted: mmap() failed: Cannot allocate memory size: 49283072 offset: 335544320
dyld4 config: DYLD_LIBRARY_PATH=/usr/lib/system/introspection DYLD_INSERT_LIBRARIES=/Developer/usr/lib/libBacktraceRecording.dylib:/Developer/usr/lib/libMainThreadChecker.dylib:/Developer/Library/PrivateFrameworks/DTDDISupport.framework/libViewDebuggerSupport.dylib
terminating with uncaught exception of type realm::AddressSpaceExhausted: mmap() failed: Cannot allocate memory size: 49283072 offset: 335544320

I have already add some code to prevent this of happen, like using

shouldCompactOnLaunch

And here is my config

var config = user.configuration(partitionValue: stationId)
        config.schemaVersion = currentVersion
        config.objectTypes = objectTypes
        config.shouldCompactOnLaunch = { (totalBytes: Int, usedBytes: Int) -> Bool in
            return true
        }

But the error still happening in some cases.

How can we avoid this crash?

Thanks

Fabrício

Can you include the section of code that’s crashing?

At any point in your code are you storing Realm objects in an array or using Swift high-level functions like filter, map or reduce?

Hi Jay,

The last log I have before the crash on write.

let newDate = Date()
do {
       try globalRealm.write {
             thawedDevice.LastActive = newDate
        }

But in app I have a lot of points where Im using swift high-level functions.

Like this:

guard var config = app.currentUser?.configuration(partitionValue: partitionValue) else { return [] }
config.schemaVersion = currentVersion
config.objectTypes = objectTypes
realm.syncSession?.suspend()
realm = try! Realm(configuration: config)
let date = NSDate()
let currentDate = Date()
let predicate = NSPredicate(format: "date > %@", date)
let tracks = realm.objects(object.self).filter(predicate).sorted(by: { $0.playtime?.start ?? currentDate < $1.playtime?.start ?? currentDate })

This function is called numerous times within 5 hours. The app only crash after a good amount of time, like 4+ hours running in background

Thanks

Fabrício

This is a total guess; the device’s memory may be getting overwhelmed.

Realm objects are lazily-loaded; meaning that when you populate a Results object with thousands of objects, the memory impact is tiny because the objects are only loaded into memory when they are used. It’s a super efficient way to handle BIG datasets.

That process only applies though, when you are working with Realm objects, filters and sorting. As soon as objects are loaded into or cast to an array, filter them using high-level Swift functions or sort them (as in your case) all of the objects get loaded into memory. So this code

let tracks = realm.objects(object.self)
                  .filter(predicate)
                  .sorted(by: { $0.playtime?.start ?? currentDate < $1.playtime?.start ?? currentDate })

starts to play nice with realm with the predicate, the sort however eliminates the lazy-loading behavior and loads all of the objects into memory. So the var tracks is not lazily loaded.

Not sure what else is going on the rest of the code but that’s a possibility (again, just a guess).

Hi @Fabricio_Masiero

In addition to what @Jay has said, does the above mean that you’re opening a realm (the same?) multiple times? If you don’t clean after yourself every time you’ve finished with it (there isn’t an explicit close(), the realm is closed when all references to it and its objects, including observers, are gone), it’s very possible that part of the memory is never released, and at some point an allocation for the memory mapping fails.

A debug run inside Xcode will tell you if the memory is constantly growing, and when done with Instruments, can also point you to what you’re actually leaving behind.