realm-swift: Uncontrolled increase of Realm database file size until app crash
Goals
I want the database to remain true-to-size
Expected Results
Going in and out of the app should result in no significant change in the size of the database file.
Actual Results
Going in and out of the app repeatedly results in a Realm Incorrect Version Exception Error. The number of records in the database remains constant, but the size of the database begins to rapidly balloon on each stop/start. Eventually the database file size expands beyond 1/2GB and the app crashes on boot because the database file is too big.
Steps to Reproduce
Happens randomly in use of a Realm database in an iOS app v2.3
Code Sample
N/A
Version of Realm and Tooling
Realm framework version: 2.3
Realm Object Server version: N/A
Xcode version: 7.3.1
iOS/OSX version: 10.3
Dependency manager + version: Cocoapods 1.2.x
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 2
- Comments: 22 (8 by maintainers)
Perhaps realm should provide it’s own method of performing background realm operations like CoreData e.g. realm.performBackgroundWrite { realm in realm.insert(object) }
This way you control over managing background realm instances (auto-releasing them), and getting the chance to commit background writes in batches.
Hi Mark – it is clear that a lot of people are having issues with uncontrolled expansion of the database file size. I hope the Realm team takes this seriously as we are going to have to migrate off Realm back to CoreData – and advise others to do the same – as there is zero excuse for a bug that turns an app into a complete lemon (due to crash on startup due to database file size) in production code.
We experience this (I guess it is the same, if not I will open a separate issue) also in the wild and I’m not sure what causes this. Our app stores data around ~20mb in the realm database at most, but we keep get reports of this:
As this happens on app start and only for some users this is hard to track.
At the point of crash we have no open instances of realm and we try to do the following:
The stack trace is also rather unintresting:
Fabric device stats tells us that there is around 2-5% of ram left when this happens but I think that is due to us trying to allocate GB’s of data…
Realm v2.4.4 Swift 3.0.2
I can’t reproduce this so sadly no sample project/… If you can give me a starting point I can try to pin this
What I also noticed is that we experience this on nearly all device types and the pretended size realm wants to mmap is only one of these four:
3221225472214748364817448304642415919104As the data we store is highly user dependent it would surprise me if these users have the same database sizes.
First, let me reiterate that large Realm files are likely due to holding old versions of data in a background thread for extended periods of time. Realms opened on threads without a runloop don’t auto-refresh, so you’ll need to take special care to wrap background Realm access in self-contained
@autoreleasepoolblocks that don’t leak any Realm-related types.However, we understand that debugging these cases can be difficult, and even if you don’t leak Realms, file sizes can be larger than you’d expect.
So I’d like to encourage everyone who’s experienced large Realm file sizes to try out the new
shouldCompactOnLaunchblock onRealm.Configuration, available as of today’s 2.6 release: https://realm.io/docs/swift/latest/#compacting-realmsI wanted to provide a default implementation so this would be on-by-default, but struggled to find good one-size-fits-all heuristics. I think some form of “compact on launch” should be Realm’s default mode of operation. So I look forward to hearing what settings people end up using in practice and what ends up working best. Please share feedback from this so we can confidently enable something like this for everyone out of the box.
We do take it seriously, but we need more information in order for this to be actionable. Firstly, we need to understand the manner in which your app is using Realm, and we can’t usefully do that for multiple people in a single GitHub issue.
@numair, since you filed this issue we can happily gather information about your situation here. A few questions:
NSOperationQueues? d. Do you use Realm on background threads that you’ve created? e. On which threads / queues do you write to the Realm? f. On which threads / queues do you read from the Realm?For other people that are seeing a similar issue, please open a new GitHub issue and provide the information described in the issue template along with answers to these questions.
Explicitly calling
invalidate()on Realm instances is one way to accomplish option 1.Please be wary of doing this outside of Realm’s provided
shouldCompactOnLaunchblock, for the reasons outlined in the blog post announcing the feature: https://news.realm.io/news/realm-objc-swift-2.6#compact-on-launchThe instructions were followed but the issue only started to happen in realm 2.2 ~ 2.4 version.