Java mmap fails on Android with “mmap failed: ENOMEM (Out of memory)”

给你一囗甜甜゛ 提交于 2019-12-05 01:20:41

Your problem is surely caused by virtual address space exhausting. Probably your problem reproduces on 32-bit Android devices, where available to user address space is physically limited to 2GB and cannot be bumped. (Although it may be 3GB (unlikely so) and it is configured during OS build process). Probably ~500 MB is used for system libraries, JVM and its heap. And ~1.5 GB is available for you.

The only way in this situation IMO - keep being mapped only file sections that are really used now and unmap unused ones as soon as possible. You can utilize some kind of sliding window where only small part of file will be mapped to memory, and when you finish - unmap that part, advance your window position and map that updated window, so on.

Also when you map whole large file - your process becomes an attractive victim for system's Out-Of-Memory killer. Because when you read such mapped file - consumption of physical memory raises and at some moment process will be killed.

Karussell

As we cannot increase the virtual address limit on Android via an API (that does not need root access), also I've not yet seen this in the Android source code. The only possible solution I see is to implement kind of a cache, which mmaps segments on access and releases older segments if a certain number of segments is already mmapped. This means we are doing the work the OS normally does for us automatically, which is a bit ugly.

To make it working under Android one can use this answer / util-mmap. Hopefully someone can implement such a mmap cache for Android at some point, maybe even us :)

try to add largeHeap in your manifest. May be it works

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!