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

Compaction causes database to double in size after first write #2631

Closed esad closed 9 years ago

esad commented 9 years ago

Today I noticed that after compacting a ~24MB realm (using writeCopyToPath), the file on disk gets reduced to ~20MB, however with first small write the file grows to ~40MB.

I'm using Realm 0.95.2.

Is this a known bug/feature?

bmunkholm commented 9 years ago

That's a known feature. When the file is out of space and needs expansion, the file will double in size up to a certain filesize after which it will only add a chunk.

esad commented 9 years ago

Is the exact behaviour documented somewhere?

Usually I wouldn't care about the file size, but Realm seems to want to mmap() the whole file into memory, and this for each thread in which there's a realm reference. As our project accesses default realm from various gcd queues, this sometimes leads to 4-6 parallel references and with database this big - we very often have OOM on devices with 512 RAM.

jpsim commented 9 years ago

Sorry for closing this a bit early, @esad. The file expansion algorithm isn't well documented anywhere publicly. On mobile platforms, Realm file size start at 4KB and double in size every time more than the current allocation is required. This doubling stops at 32MB, at which point the file grows in increments of 16MB. So 16MB -> 32MB -> 48MB.

bmunkholm commented 9 years ago

@esad: We are also working on lowering the memory needs such that only one mmap is needed in the future.

vittoriom commented 9 years ago

just out of curiosity, if the file is 48MB even though it's only using 33MB of information, do you mmap the whole file or do you strip out the padding part?

jpsim commented 9 years ago

The whole file has to be mmapped for the same reason that we can't efficiently reclaim unused space automatically: the active data isn't necessarily contiguous.