Realm is not releasing memory when going out of scope

Viewed 156

I'm using a notification service extension where memory is tight and I need to free up any RAM used by Realm after using it, however I'm finding that isn't happening.The documentation for Realm says

"There is no need to manually close a realm in Swift or Objective-C. When a realm goes out of scope and is removed from memory due to ARC , the realm is closed."

However if it really is being closed, something its memory used is not being released (at least in a notification service extension, which is what I'm concerned with). Here's some complete code for an extension which recreates this behavior (I tried it on both an iPhone mini and an iPhone 13 with identical results)

class NotificationService: UNNotificationServiceExtension {

    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        NSLog("didReceive()")
        NSSetUncaughtExceptionHandler { (exception) in
            NSLog("!! Uncaught exception \(String(describing: exception.reason))")
        }
        
        openRealm()
        let _ = getImageData()
        NSLog("Got to this point. Therefore success - no memory issue")
    }
    
    func openRealm() {
        autoreleasepool(invoking: {
            let configuration = Realm.Configuration (
                schemaVersion: 2,
                migrationBlock: { migration, oldSchemaVersion in }
            )
            do {
                let realm = try Realm(configuration: configuration)
            } catch let error as NSError {
                NSLog("\(error.code)  \(error.description)")
            }
        })
        NSLog("Opened Realm")
    }
            
    func getImageData() -> Data {
        let size = CGSize(width: 730, height: 730)
        let rendererFormat = UIGraphicsImageRendererFormat.default()
        rendererFormat.opaque = false
        let renderer = UIGraphicsImageRenderer(size: size, format: rendererFormat)
        NSLog("Aboout to render")
        let imageData = renderer.pngData { context in
            context.cgContext.setFillColor(UIColor.orange.cgColor)
            context.fill(CGRect(origin: .zero, size: contactImageSize))
            NSLog("This is the last line logged if insufficient memory")
        }
        NSLog("image created. This line not reached if insufficient memory")
        return imageData
    }
}

If this code is run as posted above, then the closure in getImageData() does not complete, the last line logged is

This is the last line logged if insufficient memory

However, if the call to openRealm() is commented out, then the closure completes and the last lines logged are:

This is the last line logged if insufficient memory
image created. This line not reached if insufficient memory
Got to this point. Therefore success - no memory issue

So, despite Realm being opened within the scope of the openRealm() function, and despite being within an autorelease pool, it is affecting the memory available to the getImageDatea() function.

Is there a way to reliably free up the memory its using?

0 Answers
Related