Memory Management in Android

Memory in JVM

One of the benefits of JVM is the isolation of memory from the host OS, so that if there are some errors in the JVM, the influence is only limited to current JVM process. Actually, the memory in a JVM can be separated to many functional parts, for the simplicity, Heap, and Stack. The Heap is this article's target,

Out of Memory Error

When the Heap size running to its limitation, the out of Memory Error throws, and the process will crash. It is really easy to repeat this Error, and just write codes to allocate memory repeatedly.

while (true) {
  byte[] twn = new byte[(int) (1024L*1024L*20)];
  mLists.add(twn);
}

If you write some cache or Memory management app, then it is really the critic part to manage the memory. There are many reasons to trigger this error, serious memory leak or memory limitation, so how to enlarge the memory limitation.

java -Xmx:1024m -Xms:512m

This is the common way for  a general java command line process, but how about the Android App?

The Android VM heap size is determined in ROM build time and is immutable for every Android devices except the rooted one. So how to configure this variable?

adb shell cat /system/build.prop

This cmd check the read-only build properties, take notice the "dalvik.vm" ones.

dalvik.vm.dex2oat-swap=false
dalvik.vm.heapstartsize=8m
dalvik.vm.heapgrowthlimit=192m
dalvik.vm.heapsize=512m
dalvik.vm.heaptargetutilization=0.75
dalvik.vm.heapminfree=512k
dalvik.vm.heapmaxfree=8m

Instead of enlarging the heap size, there are other ways to avoid this Out of Memory Error. As I mentioned the out of memory error is ejected because of the heap size reach to its limitation, what if the memory allocated but not in the heap. There are two ways to allocate memory which not accounted in heap, the Direct Buffer in NIO package, and malloc in JNI layer.

Get current process's Heap size

In Android, the max Heap size can be got by following API.

ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);

int max = manager.getMemoryClass();
int large = manager.getLargeMemoryClass();

The above API gets current process's max Heap size and the permitted largest Heap size, the size of the heap can be extended to large size only if it has specified android:largeHeap="true" in its manifest.

The other way of getting Heap size is by the Runtime.

final Runtime runtime = Runtime.getRuntime();
long free = runtime.freeMemory();
long max = runtime.maxMemory();
long total = runtime.totalMemory();

long remaining = max - totoal;

Obviously, The RunTime gives more Heap information, we can get the available memory size in time. In my opinion, this method is much more useful. Be careful, the free memory in above API is nearly useless, it represents the memory already release by JVM but still not freed to the Host.


Comments

Popular posts from this blog

Bluedroid stack in android

How to setup a NAT server?

Network programming in elisp