Android分析之LowMemoryKiller

Android分析之LowMemoryKiller
linux操作系統的傳統理念就是內存用的越多越好,儘可能拿來用,既然被儘量的使用,自然應該有清除機制。Android以linux爲基礎,自然部分繼承了這個特性。Android使用lowmemorykiller在達到某個內存門限的情況下去選擇進程刪除來釋放內存。關鍵的配置文件有如下兩個,/sys/module/lowmemorykiller/parameters/adj和/sys/module/lowmemorykiller/parameters/minfree配置系統的相關參數。
adj文件包含隊列包含oomadj隊列,當對應的minfree值達到,則進程的oomadj如果大於這個值將被殺掉。
minfree包含對應oom_adj的警戒值。
參考如下:
oom_adj 內存警戒值( 以4K爲單位)
0 1536
1 2048
2 4096
7 5120
14 5632
15 6144
一般情況下,默認設置在system/core/rootdir/init.rc中
# 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.BACKUP_APP_ADJ 2
setprop ro.HOME_APP_ADJ 4
setprop ro.HIDDEN_APP_MIN_ADJ 7
setprop ro.CONTENT_PROVIDER_ADJ 14
setprop ro.EMPTY_APP_ADJ 15

# Define the memory thresholds at which the above process classes will
# be killed. These numbers are in pages (4k).
setprop ro.FOREGROUND_APP_MEM 1536
setprop ro.VISIBLE_APP_MEM 2048
setprop ro.SECONDARY_SERVER_MEM 4096
setprop ro.BACKUP_APP_MEM 4096
setprop ro.HOME_APP_MEM 4096
setprop ro.HIDDEN_APP_MEM 5120
setprop ro.CONTENT_PROVIDER_MEM 5632
setprop ro.EMPTY_APP_MEM 6144

# Write value must be consistent with the above properties.
# Note that the driver only supports 6 slots, so we have HOME_APP at the
# same memory level as services.
write /sys/module/lowmemorykiller/parameters/adj 0,1,2,7,14,15

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

實際上在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;

根據以上分析,對於某些小內存設備,我們可以調整對應的門限值,例如:
一般調整後三個值。
echo "1536,2048,4096,15360,17920,20480">/sys/module/lowmemorykiller/parameters/minfree

http://blog.csdn.net/AndyTsui/article/details/6210653

對於應用程序

當應用程序分配內存時,會調用到dalvik/vm/alloc/HeapSource.c中的 dvmTrackExternalAllocation()方法,繼而調用到externalAllocPossible()方法,該方法要求當前堆已使用的大小(由currentHeapSize和hs->externalBytesAllocated構成)加上我們需要再次分配的內存大小不能超過堆的最大內存值,如果超過就會報錯。
有兩個地方決定了一個堆的最大內存:
1)dalvik/vm/Init.c中的
gDvm.heapSizeMax = 16 * 1024 * 1024; // Spec says 75% physical mem
2)frameworks/base/core/jni/AndroidRuntime.cpp中的
property_get("dalvik.vm.heapsize", heapsizeOptsBuf+4, "16m");
因此解決辦法就是將默認的16M改大一點。

關於內核中這部分詳細的機制,可以參看http://hubingforever.blog.163.com/blog/static/171040579201142254635562/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章