realm / realm-swift

Realm is a mobile database: a replacement for Core Data & SQLite
https://realm.io
Apache License 2.0
16.3k stars 2.14k forks source link

Error Domain=io.realm Code=1 "mmap() failed: Cannot allocate memory background thread #3083

Closed bryan1anderson closed 8 years ago

bryan1anderson commented 8 years ago

I recognize that there are several issues involving this error that have already been addressed, but in my case I feel it may be a slightly different problem.

My app on loading for the first time downloads several small images as NSData. These images are all around 50kb in size. So we're talking about maybe 3 mb of data.

This is what my code looks like:

   func addImage(objectDictionary: NSMutableDictionary, data: NSData?) {
            objectDictionary.setValue(data, forKey: "image")
            let realm = try! Realm()
            try! realm.write({ () -> Void in
                realm.create(Notifications.self, value: objectDictionary, update: true)
            })
    }

calling this function works.. but only on the main thread. So running it on any other thread returns Error Domain=io.realm Code=1 "mmap() failed: Cannot allocate memory

let backgroundQueue = dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0)
        dispatch_async(backgroundQueue, { () -> Void in
       self.addImage(objectDict, imageData)
 })

From what I've read about this error, it can happen after a huge database has been created and existed for a while. Overtime it gets too big. But my database isn't big at all. Just a few very small images. And this error only occurs when moving off of the main thread

Project info: ProductName: Mac OS X ProductVersion: 10.11.2 BuildVersion: 15C50 Xcode 7.2 Build version 7C68 0.39.0 Realm (0.97.0) RealmSwift (0.97.0) GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin15) git version 2.5.4 (Apple Git-61)

jpsim commented 8 years ago

mmap failures can also happen when the the total number of threads accessing a Realm file times the size of the file exceeds the maximum supported mmappable size on the device. How many threads are you creating here? If you're accessing a Realm from multiple threads, keeping that number as low as possible could help avoid this issue.

For every thread accessing the Realm file, the entire file must be mmapped separately. We're currently reworking our internals to support sharing these mmapped regions, which will alleviate the problem in the future (internally tracked as realm/realm-core#838).

jpsim commented 8 years ago

@bryan1anderson did my last comment help clarify the situation for you? I'm happy to answer any followup questions you may have.

jpsim commented 8 years ago

Closing this assuming my comments sufficiently covered the points brought up.