Low Memory Killer(一) - android源碼分析

標(biāo)簽: Low_Memory_Killer 低內(nèi)存管理機(jī)制 系統(tǒng)內(nèi)存管理


Low Memory Killer

Android 系統(tǒng)中運(yùn)行的APP退出到后臺(tái)時(shí)并不會(huì)真正殺死這個(gè)進(jìn)程,而是將其緩存起來(lái)述吸,以便下次能快速啟用(熱啟動(dòng))。在系統(tǒng)內(nèi)存不足情況下蝌矛,系統(tǒng)會(huì)依據(jù)Low Memory Killer機(jī)制來(lái)殺死進(jìn)程;

Low Memory Killer 基本原理

所有進(jìn)程都是從zygote孵化出來(lái)的隆豹,記錄在AMS中mLruProcesses列表中茅逮,由AMS統(tǒng)一管理,AMS中會(huì)根據(jù)進(jìn)程的狀態(tài)更新進(jìn)程對(duì)應(yīng)的oom_adj值献雅,這個(gè)值會(huì)通過(guò)文件傳遞到kernel中,kernel有個(gè)低內(nèi)存回收機(jī)制侯谁,在內(nèi)存達(dá)到一定的閥值時(shí)會(huì)觸發(fā)清理oom_adj值高的進(jìn)程騰出更多內(nèi)存空間

Low Memory Killer 實(shí)現(xiàn)方案

先看android手機(jī)中的倆個(gè)文件
/sys/module/lowmemorykiller/parameters/minfree //文件中每一個(gè)數(shù)字代表一個(gè)內(nèi)存級(jí)別

bullhead:/ # cat /sys/module/lowmemorykiller/parameters/minfree //文件中每一個(gè)數(shù)字代表一個(gè)內(nèi)存級(jí)別
18432,23040,27648,32256,55296,80640

cat /sys/module/lowmemorykiller/parameters/adj //文件中每一個(gè)數(shù)字代表一個(gè)進(jìn)程優(yōu)先級(jí)級(jí)別

bullhead:/ # cat /sys/module/lowmemorykiller/parameters/adj //文件中每一個(gè)數(shù)字代表一個(gè)進(jìn)程優(yōu)先級(jí)級(jí)別
0,100,200,300,900,906

當(dāng)系統(tǒng)剩余內(nèi)存低于80640的時(shí)候章钾,系統(tǒng)會(huì)殺死adj>=906級(jí)別的進(jìn)程
當(dāng)系統(tǒng)剩余內(nèi)存低于55296的時(shí)候,系統(tǒng)會(huì)殺死adj>=900級(jí)別的進(jìn)程
當(dāng)系統(tǒng)剩余內(nèi)存低于32256的時(shí)候伍玖,系統(tǒng)會(huì)殺死adj>=300級(jí)別的進(jìn)程
當(dāng)系統(tǒng)剩余內(nèi)存低于27648的時(shí)候,系統(tǒng)會(huì)殺死adj>=200級(jí)別的進(jìn)程
當(dāng)系統(tǒng)剩余內(nèi)存低于23040的時(shí)候,系統(tǒng)會(huì)殺死adj>=100級(jí)別的進(jìn)程

對(duì)于應(yīng)用進(jìn)程來(lái)說(shuō)丽旅,應(yīng)用進(jìn)程自身也有adj,應(yīng)用進(jìn)程自身adj由AMS負(fù)責(zé)更新邪狞;

ADJ 調(diào)整算法

ActivityManagerService 中三個(gè)核心方法:

updateOomAdjLocked:更新adj,當(dāng)目標(biāo)進(jìn)程為空帆卓,或者被殺則返回false;否則返回true;
computeOomAdjLocked:計(jì)算adj剑令,返回計(jì)算后RawAdj值;
applyOomAdjLocked:應(yīng)用adj,當(dāng)需要?dú)⒌裟繕?biāo)進(jìn)程則返回false吁津;否則返回true。

    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
            ProcessRecord TOP_APP, boolean doingAll, long now) {
        if (app.thread == null) {
            return false;
        }

        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);

        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
    }

ADJ更新的地方

即調(diào)用updateOomAdjLocked方法的地方

Activity

  • ActivityStackSupervisor.realStartActivityLocked() //啟動(dòng)Activity
  • ActivityStack.resumeTopActivityInnerLocked //恢復(fù)棧頂Activity
  • ActivityStack.finishSubActivityLocked //finish掉上一個(gè)Activity
  • ActivityStack.finishVoiceTask //
  • ActivityStack.finishCurrentActivityLocked //結(jié)束當(dāng)前Activity
  • ActivityStack.destroyActivityLocked //摧毀當(dāng)前Activity

Service

  • ActiveServices.bindServiceLocked //綁定服務(wù)(只更新當(dāng)前app)
  • ActiveServices.unbindServiceLocked //解綁服務(wù) (只更新當(dāng)前app)
  • ActiveServices.realStartServiceLocked //啟動(dòng)服務(wù)
  • ActiveServices.sendServiceArgsLocked //在bringup或則cleanup服務(wù)過(guò)程調(diào)用(只更新當(dāng)前app)
  • ActiveServices.bringDownServiceLocked //結(jié)束服務(wù) (只更新當(dāng)前app)
  • ActiveServices.removeConnectionLocked //清除掉此進(jìn)程的所有服務(wù)連接
  • ActiveServices.serviceDoneExecutingLocked //進(jìn)程服務(wù)出現(xiàn)異常(ANR或其他異常)梭依,移除timeout消息

廣播

  • BroadcastQueue.processCurBroadcastLocked //處理當(dāng)前廣播
  • BroadcastQueue.deliverToRegisteredReceiverLocked //分發(fā)已注冊(cè)的廣播 (只更新當(dāng)前app)
  • BroadcastQueue.processNextBroadcast //處理下一個(gè)廣播

Process

  • ActivityManagerService.setSystemProcess //創(chuàng)建并設(shè)置系統(tǒng)進(jìn)程
  • ActivityManagerService.appDiedLocked //進(jìn)程死亡
  • ActivityManagerService.killAllBackgroundProcesses //殺死所有后臺(tái)進(jìn)程.即(ADJ>900或removed=true的普通進(jìn)程)
  • ActivityManagerService.killPackageProcessesLocked //以包名的形式 殺掉相關(guān)進(jìn)程;
  • ActivityManagerService.attachApplicationLocked //進(jìn)程創(chuàng)建后attach到system_server的過(guò)程;
  • ActivityManagerService.importanceTokenDied // 重要進(jìn)程死亡
  • ActivityManagerService.setProcessImportant//例如Toast彈出過(guò)程,設(shè)置進(jìn)程優(yōu)先級(jí)
  • ActivityManagerService.getContentProviderImpl //獲取provider (只更新當(dāng)前app)
  • ActivityManagerService.removeContentProvider // 移除provider
  • ActivityManagerService.publishContentProviders //發(fā)布provider (只更新當(dāng)前app)
  • ActivityManagerService.removeContentProviderExternalUnchecked
  • ActivityManagerService.publishContentProviders //發(fā)布provider (只更新當(dāng)前app)
  • ActivityManagerService.addAppLocked // 創(chuàng)建persistent進(jìn)程
  • ActivityManagerService.updateSleepIfNeededLocked //進(jìn)程休眠相關(guān)
  • ActivityManagerService.setHasTopUi //
  • ActivityManagerService.bindBackupAgent //
  • ActivityManagerService.unbindBackupAgent //
  • ActivityManagerService.updateProcessForegroundLocked //將app從前臺(tái)進(jìn)程移除
  • ActivityManagerService.setAppIdTempWhitelistStateLocked //
  • ActivityManagerService.setUidTempWhitelistStateLocked //
  • ActivityManagerService.trimApplications //清除沒(méi)有使用app
  • ActivityManagerService.setHasOverlayUi //

以上就是Low Memory Killer 調(diào)用地方和算法框架;下篇文章講解Low Memory Killer如何將ADJ參數(shù)傳遞到底層kernel,kernel如何進(jìn)行內(nèi)存回收

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末钾埂,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子淤击,更是在濱河造成了極大的恐慌,老刑警劉巖污抬,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件绳军,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡门驾,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)楣责,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人秆麸,你說(shuō)我怎么就攤上這事及汉。” “怎么了坷随?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵驻龟,是天一觀的道長(zhǎng)缸匪。 經(jīng)常有香客問(wèn)我,道長(zhǎng)豪嗽,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任隐锭,我火速辦了婚禮计贰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘躁倒。我一直安慰自己,他們只是感情好秧秉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著象迎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪砾淌。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,578評(píng)論 1 305
  • 那天赃春,我揣著相機(jī)與錄音,去河邊找鬼织中。 笑死衷戈,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的脱惰。 我是一名探鬼主播窿春,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼采盒,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼磅氨!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起烦租,我...
    開(kāi)封第一講書(shū)人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤除盏,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后者蠕,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡粪小,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年探膊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片逞壁。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡究抓,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出刺下,到底是詐尸還是另有隱情,我是刑警寧澤橘茉,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站擅腰,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏趁冈。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一沐绒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧乔遮,春花似錦、人聲如沸蹋肮。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)病毡。三九已至,卻和暖如春啦膜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背僧家。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留八拱,地道東北人阵赠。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓清蚀,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親枷邪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容