Memory mapping a large file on Android in Java works good. But when mapping more than ~1.5GB in total even with multiple mapping calls it fails with:
mmap failed: ENOMEM (Out of memory)
See the full discussion here. Note: It does not fail on a server Linux. The android:largeHeap="true" is enabled for the application.
The following Java code is called a few hundred times requesting ~1MB per call:
ByteBuffer buf = raFile.getChannel().map(allowWrites ? FileChannel.MapMode.READ_WRITE : FileChannel.MapMode.READ_ONLY, offset, byteCount);
to avoid requesting one large contiguous memory chunk which is often harder to be found. See the full code here. Keep in mind that doubling the 'segment size' (i.e. the size of a single map call) has no effect, which means it stops at the similar memory position. Also it is important to note that 2 apps with both slightly under the limit are executing fine (hinting to a per process limit).
Related questions are here, here, here, here, here, here, here and here.
Will using multiple files instead of one file with multiple mappings help?
I've read that this could be a per process limit for the virtual address space. Where can I find more about this? Can I change this setting with NDK e.g. how to call ulimit
? Could madvise help me a bit here?
Update
See my answer here for a mmap tool usable in Java