How to work around Android’s 24 MB memory limit
2012-10-25 10:42
501 查看
The Android framework enforces a per-process 24 MB memory limit. On some older devices, such as the G1, the limit is even lower at 16 MB.
What’s more, the memory used by Bitmaps is included in the limit. For an application manipulating images it is pretty easy to reach this limit and get the process killed with an OOM exception:
E/dalvikvm-heap(12517): 1048576-byte external allocation too large for this process.
E/GraphicsJNI(12517): VM won't let us allocate 1048576 bytes
D/AndroidRuntime(12517): Shutting down VM
W/dalvikvm(12517): threadid=1: thread exiting with uncaught exception (group=0x4001d7f0)
E/AndroidRuntime(12517): FATAL EXCEPTION: main
E/AndroidRuntime(12517): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
This limit is ridiculously low. For a device, like the Nexus One, with 512MB of physical RAM, setting the per-process memory limit for the foreground activity to only 5% of the RAM is a silly mistake. But anyway, that’s how things are and we have to live with
it — i.e. find how to work around it.
There are two ways to allocate much more memory than the limit:
One way is to allocate memory from native code. Using the NDK (native development kit) and JNI, it’s possible to allocate memory from the C level (e.g. malloc/free or new/delete), and such allocations are not counted towards the 24 MB limit. It’s true, allocating
memory from native code is not as convenient as from Java, but it can be used to store some large amounts of data in RAM (even image data).
Another way, which works well for images, is to use OpenGL textures — the texture memory is not counted towards the limit.
To see how much memory your app has really allocated you can use android.os.Debug.getNativeHeapAllocatedSize().
Using either of the two techniques presented above, on a Nexus One, I could easily allocate 300MB for a single foreground process — more than 10 times the default 24 MB limit.
What’s more, the memory used by Bitmaps is included in the limit. For an application manipulating images it is pretty easy to reach this limit and get the process killed with an OOM exception:
E/dalvikvm-heap(12517): 1048576-byte external allocation too large for this process.
E/GraphicsJNI(12517): VM won't let us allocate 1048576 bytes
D/AndroidRuntime(12517): Shutting down VM
W/dalvikvm(12517): threadid=1: thread exiting with uncaught exception (group=0x4001d7f0)
E/AndroidRuntime(12517): FATAL EXCEPTION: main
E/AndroidRuntime(12517): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
This limit is ridiculously low. For a device, like the Nexus One, with 512MB of physical RAM, setting the per-process memory limit for the foreground activity to only 5% of the RAM is a silly mistake. But anyway, that’s how things are and we have to live with
it — i.e. find how to work around it.
There are two ways to allocate much more memory than the limit:
One way is to allocate memory from native code. Using the NDK (native development kit) and JNI, it’s possible to allocate memory from the C level (e.g. malloc/free or new/delete), and such allocations are not counted towards the 24 MB limit. It’s true, allocating
memory from native code is not as convenient as from Java, but it can be used to store some large amounts of data in RAM (even image data).
Another way, which works well for images, is to use OpenGL textures — the texture memory is not counted towards the limit.
To see how much memory your app has really allocated you can use android.os.Debug.getNativeHeapAllocatedSize().
Using either of the two techniques presented above, on a Nexus One, I could easily allocate 300MB for a single foreground process — more than 10 times the default 24 MB limit.
相关文章推荐
- How to discover memory usage of my application in Android
- Howto find native code memory leak in Android
- Howto find native code memory leak in Android
- 【iMX6QD】 How to Add 24-bit LVDS Support in Android
- You probably tried to upload too large file. Please refer to documentation for ways to workaround this limit.
- You probably tried to upload too large file. Please refer to documentation for ways to workaround this limit.
- How to check memory leaks in android app?
- How to discover memory usage of my application in Android
- How to Increase the Memory Limit for 32-bit Applications in Windows 64-bit OS
- How to discover memory usage of my application in Android
- [知其然不知其所以然-30] How to work around when system can not be woken up
- How to increase MySQL memory limit?
- How to discover memory usage of my application in Android
- How to Limit NodeRunner.exe High Memory, CPU Usage
- Windows CE memory limit workaround
- 【iMX6QD】 How to Add 24-bit LVDS Support in Android
- How to work around a possible XNA Game Studio or Windows Phone SDK install failure on Windows 8
- How to workaround the IE default behavior of re-posting the entire form when pressing "刷新"(or F5)
- A workaround to change shared memory size for Docker containers in AWS ECS
- Pulling Memory off an Android Device How To!