邊實驗邊分析 - Android LowMemoryKiller 介紹

一、簡述

在Linux中,存在著一個OOM 终结者(Out Of Memory killer),他會在内存過低的情況下,殺掉你的進程,來釋放空閑的内存維持正常的運作。Android中也不一例外的存在者一個殺手,但是他不叫OOM殺手,而叫做LMK殺手(Android LowMemoryKiller),具體的原理不在這裏闡述,想知道的朋友可以自行Google一下,我們這裏只要知道這個殺手,他會在機器内存不足的情況下,進行殺掉進程的動作,而這個殺手不是隨便濫殺,而是有目標的,這個目標是由ActivityManagerService去指定並更新的,ActivityManagerService會將所有進程進行分類,並會調整每個進程的分類以及給一個分值來表示,該分值越高,越容易成爲殺手的目標而被幹掉,這個分值被保存在proc/{pid}/oom_score_adj下。

二、Process 分類

分類的具體定義值,我們可以在Android的com.android.server.am.ProcessList裏面查看到:
在这里插入图片描述
比如上圖中的FOREGROUND_APP_ADJ的值為0,則查看他的oom_score_adj的分值會是0,表示該APP當前在前臺可見狀態,再比如NATIVE_ADJ為-1000,則説明是Native的進程,複數可以認爲基本上不會被殺手給幹掉的進程,而超過900的進程,則會很容易安排給殺手了,這個進程的APP,會被歸類為Cache APP。

三、Android 7.0以下及7.0以上的區別

這裏需要注意一點需要説明一下,在Android 7.0上系統會直接根據ProcessList的定義寫入oom_score_adj值,這個值是100,200,-1000這樣的大值,這樣的好處是可以表示一個範圍,便於更加細化ADJ;而在7.0以下的系統,ProcessList的值對應的是oom_adj裏面的值,這個值是1,2,-17這樣的值,這個oom_score_adj值是通過了oom_adj計算得出的(大致的計算公式可以參考:oom_adj * 1000 / 17),所以如果你要在7.0以下的系統中查看oom_adj的值的話,建議查看proc/{id}/oom_adj的值,這個值會和ProcessList的值對的起來一些,方便查看。

四、ADJ查看方式

知道了上述的知識點后,下一步我們就可以實際的來查看一下該ADJ值了,
這邊我們可以通過dumpsys meminfo先來查看一下系統給我們APP進行的分類情況:

dumpsys meminfo 查看到所有的進程分類
在这里插入图片描述
而知道了這個分類信息后,可以利用cat proc/{id}/oom_adj查看對應的進程

cat proc/{pid}/oom_score_adj
在这里插入图片描述
可以看到com.oppo.launcher的進程ADJ值為0,説明他在前臺可見狀態(因爲我停留在了桌面,而launcher就是這個桌面程序),所以不會被系統幹掉的。
現在我打開任意一個APP,再次查看的時候,會發現該值已經變成了100。
在这里插入图片描述

五、總結

使用上述的方法,基本上能夠幫你對process的進程有了一個大概的瞭解了,至於想知道具體細節的朋友,可以自己去查看一些源碼知識,加深一些這方面的理解,我這邊給出一個我自己總結的源碼中能追蹤到Android Manager Service修改adj值的一個方法路綫作爲參考,請結合Android 9.0源碼進行查看:

set oom_adj流程:主要通過ActivityManagerService裏的updateOomAdjLocked(舊版本會調用applyOomAdjLocked)方法寫入ADJ,ProcessList裏面會傳調用ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
setOomAdj方法通過localSocket與底層system/memory/lmkd/lmkd.cpp ->ctrl_data_handler -> ctrl_command_handler方法進行處理command,(具體command的格式參考這個裏面https://jekton.github.io/2019/03/21/android9-lmk-lmkd/),ctrl_data_read方法讀取出來command值,
lmkd_pack_get_cmd讀取出來package信息包括adj。writefilestring方法寫入進/proc/%d/oom_score_adj中。

可以看到其實android是通過localSocket與底層進行的通訊,是不是對這一塊内容又瞭解了許多了呢?

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卡卡爾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值