I found writing huge amount of data to Realm in iOS causes out of memory and crash. After days of investigation, I found that Realm does not release unused objects in a List. I ran the following example:
class LeakTestList : Object{
var items = List<LeakTestItem>()
}
class LeakTestItem : Object{
@objc dynamic var data = 0
}
func leakTest()
{
guard let realm = try? Realm() else
{
return
}
let leakTestList = LeakTestList()
leakTestList.items.append(objectsIn: (0..<10000).map{LeakTestItem(value: ["data":$0])})
try? realm.write {
realm.add(leakTestList)
}
}
After leakTest()
return, I got the following memory profile:
LeakTestList
has already gone but all the items remains in memory. This cause out of memory when I tried to write a lot of list items even divided into multiple short enough lists. Is this a bug from Realm or is there anything I can do to solve the problem?
Referring to @Jay 's answer, I am able to remove the memory footprint of the realm objects from the memory monitor, but the memory usage stay the same until viewDidLoad()
end. After more digging, turns out the key idea I missed was to wrap everything in autoreleasepool
. Referring to this article : https://realm.io/docs/cookbook/swift/object-to-background/
func leakTest()
{
autoreleasepool {
guard let realm = try? Realm() else
{
return
}
let leakTestList = LeakTestList()
try? realm.write {
realm.add(leakTestList)
}
try? realm.write {
leakTestList.items.append(objectsIn: (0..<10000).map{LeakTestItem(value: ["data":$0])})
}
}
}