Senin, 27 Desember 2010

LowMemoryKiller in Android

LowMemoryKiller in Android
Android uses lowmemorykiller driver to kill selected process and free the memory, when some kind of low memory thresholds is met. Two files are generated in /sys file system for system tuning.

1. /sys/module/lowmemorykiller/parameters/adj
This file includes the oomadj array. If the corresponding minfree data is met, one of the process which oomadj are larger than this number will be killed.
About oomadj, the factor is introduced by OOMkiller module in the kernel. It is a property of the process. The range is from -17 to +15, the higher the score, more likely the associated process is to be killed by oom-killer. Lowmemorykiller use this score as well.
http://www.chineselinuxuniversity.net/articles/19534.shtml

2. /sys/module/lowmemorykiller/parameters/minfree
This file includes the threshold numbers for minfree memory size. The unit is page.

Example in Android
The default setting is in system/core/rootdir/init.rc.
# Write value must be consistent with the above properties.
write /sys/module/lowmemorykiller/parameters/adj 0,1,2,7,14,15

write /proc/sys/vm/overcommit_memory 1
write /sys/module/lowmemorykiller/parameters/minfree 1536,2048,4096,5120,5632,6144

# Set init its forked children's oom_adj.
write /proc/1/oom_adj -16

This means if the free memory is smaller than 1536*4K=6MB, one of the processes which adj is larger than 0 will be killed. If the free memory is smaller than 2048*4K=8MB, the process adj larger than 1 will be killed. And so on.

On the other hand, Android put the processes into 6 classes.
# Define the oom_adj values for the classes of processes that can be
# killed by the kernel. These are used in ActivityManagerService.
setprop ro.FOREGROUND_APP_ADJ 0
setprop ro.VISIBLE_APP_ADJ 1
setprop ro.SECONDARY_SERVER_ADJ 2
setprop ro.HIDDEN_APP_MIN_ADJ 7
setprop ro.CONTENT_PROVIDER_ADJ 14
setprop ro.EMPTY_APP_ADJ 15

Say, the FOREGROUND application has the highest priority, the least likely to be killed. The CONTENT_PROVIDER and EMPTY_APP will be killed at first. Confusion here is we know the activity is the one people can see from UI. It actually means the process has foreground activity will have the highest priority, and the process which hosts the activity visible to user has the second priority.

Actually it defines two more priorities as below, in frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
// This is a process running a core server, such as telephony. Definitely
// don't want to kill it, but doing so is not completely fatal.
static final int CORE_SERVER_ADJ = -12;

// The system process runs at the default adjustment.
static final int SYSTEM_ADJ = -16;

In the ActivityManagerService, it starts some core service in a process and assigns it to SYSTEM_ADJ score.
ActivityManagerService.java did some other works as well. For example, it tracks which activity is running in background and foreground, and so it has use-count reference for the process. The java file is 11508 lines, like a monster.

To customize for some short-of-memory devices, we could change the threshold value accordingly. For example:
write /sys/module/lowmemorykiller/parameters/minfree 1536, 4096, 4096, 5120,5632,6144
This makes the driver kill the processes as early as possible. So the new application could get more memory.

sumber
http://swcai.blogspot.com/2009/02/lowmemorykiller-in-android.html