【Android】LMK 工作機制


Android分析之LowMemoryKiller

 

 

Android Kernel 會定時執行一次檢查,殺死一些進程,釋放掉內存。

    那么,如何來判斷,那些進程是需要殺死的呢?答案就是我們的標題:Low memory killer機制。

 

Low memory killer 則是定時進行檢查。

Low memory killer 主要是通過進程的oom_adj 來判定進程的重要程度。這個值越小,程序越重要,被殺的可能性越低。

oom_adj的大小和進程的類型以及進程被調度的次序有關。

Low memory killer 的具體實現可參看:kernel/drivers/misc/lowmemorykiller.c 

1.oom_adj的值是如何賦予的

 

進程的類型,可以在ActivityManagerService中清楚的看到: 

    static final int EMPTY_APP_ADJ;

    static final int HIDDEN_APP_MAX_ADJ;

    static final int HIDDEN_APP_MIN_ADJ;

    static final int HOME_APP_ADJ;

    static final int BACKUP_APP_ADJ;

    static final int SECONDARY_SERVER_ADJ;

    static final int HEAVY_WEIGHT_APP_ADJ;

    static final int PERCEPTIBLE_APP_ADJ;

    static final int VISIBLE_APP_ADJ;

    static final int FOREGROUND_APP_ADJ;

    static final int CORE_SERVER_ADJ = -12;

    static final int SYSTEM_ADJ = -16; 

   ActivityManagerService定義各種進程的oom_adj,CORE_SERVER_ADJ代表一些核心的服務的omm_adj,數值為-12,這類進程永遠也不會被殺死。

其他未賦值的都在static塊中進行了初始化,是通過system/rootdir/init.rc進行配置的:

 

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.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.HIDDEN_APP_MEM 5120

   setprop ro.CONTENT_PROVIDER_MEM 5632

   setprop ro.EMPTY_APP_MEM 6144

 

配置文件有如下兩個:

/sys/module/lowmemorykiller/parameters/adj

/sys/module/lowmemorykiller /parameters/minfree

owmeme_adj中各項數值代表閾值的警戒級數,

lowmem_minfree代表對應級數的剩余內存。

adj文件存放着oom_adj 內存警戒值( 以4K為單位)
 
0 1536 
1 2048 
2 4096 
7 5120 
14 5632 
15 6144

 

 

也就是說,當系統的剩余內存為小於6MB時候,警戒級數為0,當系統內存剩余小於8M而大於
6M的時候,警戒級數為1,當內存小於64M大於16MB的時候,警戒級數為12.

 

 

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

 

原文作者:AndyTsui

原文鏈接:http://blog.csdn.net/AndyTsui/archive/2011/02/27/6210653.aspx

2.LMK的工作機制

 
LMK開始工作時,
首先根據閾值表確定當前的警戒級數,則高於警戒級數的進程是待殺的范圍。
然后遍歷所有進程的oom_adj值,找到大於min_adj的進程,若找到多個,則把占用進程最大的進程存放在selected中。
 
最關鍵的一步就是,發送SIGKILL信息,殺掉該進程。
 

3.tips

 
(1)在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
 
   class_start default
 
         

(2)進程oom_adj同樣可以進行設置,通過write /proc/<PID>/oom_adj  ,在init.rc中,init進程的pid1omm_adj被配置為-16,永遠不會被殺死。

   # Set init its forked children's oom_adj.
   write /proc/1/oom_adj -16
(3)dumpsys activity可以dump進程的信息,查看adj值
   procrank可以查看進程占用內存大小

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM