As I know, android used a non-compacting GC before 3.0(
https://groups.google.com/forum/#!topic/android-developers/7VeEnvcF1CE), which will not return the vm memory to system for external memory(non-vm-memory) using, but the external memory can be returned to system for vm memory using. For example:
// Assuming the memory limit of process is 24M, and the usage of memory of a app now is 1M/2M(vm), 1M/2M(external)
byte [] tmp = new byte[1024*1024*20]; // 21M/22M, 1M/2M
tmp = null;
system.gc();//1M/22M, 1M/2M, there are 22M vm-memory allocated, 1M used, 21M free;
//trying to allocate 3M-external memory will cause an OOM, because the heap don't shrink for external memory.
new Bitmap(xx); //before android 3.0, bitmap alloacate in external memory.
//or
ByteBuffer.allocateDirect(3*1024*1024);
So if I want to avoid OOM, I must control the peak of vm memory.
I found when loading/uploading asserts(models and textures), the engine will cause a high peak of memory usage, when all things done(after uploading/virtualizing), the peak will drop down much(but the vm memory won't return as saying before). So when I finished 3D-scene, return to 2D view activity(with many bitmaps\external memory), the OOM happens frequently. There is enough memory, but the peak is unreasonable.
Could I decrease the peak of vm memory when loading/uploading assets? For example:
Decreasing the tmp buffer for uploading(for 16-depth bitmap, using short[] instead of int[]);
Converting-uploading-freeing memory of asserts one at a time, instead of converting all -> uploading all -> freeing all