[Android]你不知道的Android进程化(3)--进程等级
我們可以看到現(xiàn)在Android的運(yùn)行內(nèi)存越來(lái)越大,6G、8G的大內(nèi)存時(shí)代,越大運(yùn)存將允許運(yùn)行越多的app,而Android系統(tǒng)也組建增大進(jìn)程可以申請(qǐng)的最大運(yùn)存量。Android 系統(tǒng)將盡量長(zhǎng)時(shí)間地保持應(yīng)用進(jìn)程,內(nèi)存是有限的,為了新建進(jìn)程或運(yùn)行更重要的進(jìn)程,最終需要移除舊進(jìn)程來(lái)回收內(nèi)存。
為了確定哪些進(jìn)程是能夠被移除的,Android系統(tǒng)引用了進(jìn)程優(yōu)先級(jí)別的機(jī)制。Android進(jìn)程的優(yōu)先層級(jí)結(jié)構(gòu)一共分5層。
1.前臺(tái)進(jìn)程:(foreground process)
用戶當(dāng)前操作所必需的進(jìn)程。如果一個(gè)進(jìn)程滿足以下任一條件,即視為前臺(tái)進(jìn)程:
(1)用戶正在交互使用的 Activity(已調(diào)用 Activity 的 onResume() 方法)
(2)某個(gè) Service,后者綁定到用戶正在交互的 Activity。
(3)正在“前臺(tái)”運(yùn)行的 Service(服務(wù)已調(diào)用 startForeground())
(4)正執(zhí)行一個(gè)生命周期回調(diào)的 Service(onCreate()、onStart() 或 onDestroy())
(5)正執(zhí)行其 onReceive() 方法的 BroadcastReceiver
通常,在任意給定時(shí)間前臺(tái)進(jìn)程都為數(shù)不多。只有在內(nèi)存不足以支持它們同時(shí)繼續(xù)運(yùn)行這一萬(wàn)不得已的情況下,系統(tǒng)才會(huì)終止它們。 此時(shí),設(shè)備往往已達(dá)到內(nèi)存分頁(yè)狀態(tài),因此需要終止一些前臺(tái)進(jìn)程來(lái)確保用戶界面正常響應(yīng)。
2.可見(jiàn)進(jìn)程:
沒(méi)有任何前臺(tái)組件、但仍會(huì)影響用戶在屏幕上所見(jiàn)內(nèi)容的進(jìn)程。 如果一個(gè)進(jìn)程滿足以下任一條件,即視為可見(jiàn)進(jìn)程:
(1)不在前臺(tái)、但仍對(duì)用戶可見(jiàn)的 Activity(已調(diào)用其 onPause() 方法)。例如,如果前臺(tái) Activity 啟動(dòng)了一個(gè)對(duì)話框,允許在其后顯示上一 Activity,則有可能會(huì)發(fā)生這種情況。
(2)綁定到可見(jiàn)(或前臺(tái))Activity 的 Service。 (不包含startForground()的情況)
可見(jiàn)進(jìn)程被視為是極其重要的進(jìn)程,除非為了維持所有前臺(tái)進(jìn)程同時(shí)運(yùn)行而必須終止,否則系統(tǒng)不會(huì)終止這些進(jìn)程。
3.服務(wù)進(jìn)程
正在運(yùn)行已使用 startService() 方法啟動(dòng)的服務(wù)且不屬于上述兩個(gè)更高類別進(jìn)程的進(jìn)程。盡管服務(wù)進(jìn)程與用戶所見(jiàn)內(nèi)容沒(méi)有直接關(guān)聯(lián),但是它們通常在執(zhí)行一些用戶關(guān)心的操作(例如,在后臺(tái)播放音樂(lè)或從網(wǎng)絡(luò)下載數(shù)據(jù))。因此,除非內(nèi)存不足以維持所有前臺(tái)進(jìn)程和可見(jiàn)進(jìn)程同時(shí)運(yùn)行,否則系統(tǒng)會(huì)讓服務(wù)進(jìn)程保持運(yùn)行狀態(tài)。
4.后臺(tái)進(jìn)程:
包含目前對(duì)用戶不可見(jiàn)的 Activity 的進(jìn)程(已調(diào)用 Activity 的 onStop() 方法)。這些進(jìn)程對(duì)用戶體驗(yàn)沒(méi)有直接影響,系統(tǒng)可能隨時(shí)終止它們,以回收內(nèi)存供前臺(tái)進(jìn)程、可見(jiàn)進(jìn)程或服務(wù)進(jìn)程使用。 通常會(huì)有很多后臺(tái)進(jìn)程在運(yùn)行,因此它們會(huì)保存在 LRU (最近最少使用)列表中,以確保包含用戶最近查看的 Activity 的進(jìn)程最后一個(gè)被終止。如果某個(gè) Activity 正確實(shí)現(xiàn)了生命周期方法,并保存了其當(dāng)前狀態(tài),則終止其進(jìn)程不會(huì)對(duì)用戶體驗(yàn)產(chǎn)生明顯影響,因?yàn)楫?dāng)用戶導(dǎo)航回該 Activity 時(shí),Activity 會(huì)恢復(fù)其所有可見(jiàn)狀態(tài)。 有關(guān)保存和恢復(fù)狀態(tài)的信息,請(qǐng)參閱 Activity文檔。
5.空進(jìn)程
不含任何活動(dòng)應(yīng)用組件的進(jìn)程。保留這種進(jìn)程的的唯一目的是用作緩存,以縮短下次在其中運(yùn)行組件所需的啟動(dòng)時(shí)間。 為使總體系統(tǒng)資源在進(jìn)程緩存和底層內(nèi)核緩存之間保持平衡,系統(tǒng)往往會(huì)終止這些進(jìn)程。
根據(jù)進(jìn)程中當(dāng)前活動(dòng)組件的重要程度,Android 會(huì)將進(jìn)程評(píng)定為它可能達(dá)到的最高級(jí)別。例如,如果某進(jìn)程托管著服務(wù)和可見(jiàn) Activity,則會(huì)將此進(jìn)程評(píng)定為可見(jiàn)進(jìn)程,而不是服務(wù)進(jìn)程。
連接adb命令,使用dumpsys meminfo命令時(shí),會(huì)列出當(dāng)前系統(tǒng)的所有進(jìn)程,不同進(jìn)程放入不同的分類。
Linux API:
Linux提供了兩個(gè)API用于設(shè)置調(diào)度優(yōu)先級(jí)及調(diào)度策略。
其中,which和who聯(lián)合使用。
當(dāng)which為PRIO_PROGRESS時(shí),who代表一個(gè)進(jìn)程,即pid;
當(dāng)which為PRIO_PGROUP時(shí),who代表一個(gè)進(jìn)程組,即gid;
當(dāng)which為PRIO_USER時(shí),who代表一個(gè)用戶,即uid。
prio用于設(shè)置進(jìn)程的nice值,取值范圍為-20~+19。
該值越大表示進(jìn)程越友好(nice),即對(duì)CPU資源的依賴越低。
于是,進(jìn)程的prio值越大,其被調(diào)用的優(yōu)先級(jí)越低。
其中,pid表示進(jìn)程id。
policy表示調(diào)度策略。
Linux定義了很多種調(diào)度策略,具體的內(nèi)容可以參考相關(guān)的資料。
param參數(shù)中,最重要的是該結(jié)構(gòu)體中的sched_priority變量。
該變量用于設(shè)置該調(diào)度策略下,進(jìn)程的優(yōu)先級(jí)。
以上只是簡(jiǎn)單的進(jìn)程級(jí)別分類,如果按照l(shuí)owmeorykiller中進(jìn)程的分類將會(huì)更為完整一點(diǎn)。
每一類別的進(jìn)程會(huì)有其oom_adj值的取值范圍,oom_adj值越高則代表進(jìn)程越不重要,在系統(tǒng)執(zhí)行低內(nèi)存殺進(jìn)程操作時(shí),會(huì)從oom_adj值越高的開(kāi)始?xì)ⅰ?br />ProcessList中記錄了進(jìn)程的等級(jí)判斷
系統(tǒng)級(jí)別的進(jìn)程都是使用負(fù)數(shù)的進(jìn)程級(jí)別,所以不會(huì)被判定回收
系統(tǒng)級(jí)別進(jìn)程
oom_adj是每進(jìn)程的進(jìn)程級(jí)別。
如何查看某個(gè)應(yīng)用的oom_adj數(shù)值?
首先adb shell#ps查看應(yīng)用的PID。
然后#cat /proc/PID/oom_adj的結(jié)果就是。
此源碼是android 7.1.1源碼,可能舊的源碼等級(jí)數(shù)字會(huì)小一點(diǎn)。
前臺(tái)進(jìn)程 oom_adj 0
可見(jiàn)進(jìn)程 oom_adj 100
可感知進(jìn)程 oom_adj 200
后臺(tái)進(jìn)程 oom_adj 300
后臺(tái)重量級(jí)進(jìn)程 oom_adj 400
服務(wù)進(jìn)程 oom_adj 500
Home進(jìn)程 oom_adj 600
前一個(gè)進(jìn)程 oom_adj 700
服務(wù)進(jìn)程 oom_adj 800
緩存進(jìn)程 oom_adj 900~906
其職能和舊版本的Android并沒(méi)不同,可以借鑒# 溪亭瀝酒的下圖
當(dāng)需要釋放內(nèi)存,運(yùn)行新的app的時(shí)候,進(jìn)程oom_adj數(shù)值越高,進(jìn)程就越容易被lowmemroykiller殺死回收。
在ActivityManager當(dāng)中又自有一套進(jìn)程分級(jí),而且更加詳細(xì)的級(jí)別,和ProcessList中的某些等級(jí)是對(duì)應(yīng)的,可以從ProcessList中看出。(圖中等級(jí)并不是全部等級(jí))
AMS內(nèi)部就是使用這份進(jìn)程等級(jí)記錄。
內(nèi)存管理進(jìn)程是以一種類似Lru模型來(lái)做的。
了解進(jìn)程等級(jí),對(duì)以后進(jìn)程保活,進(jìn)程調(diào)度有更加深刻的認(rèn)識(shí)。
剛開(kāi)始都是說(shuō)一些比較基礎(chǔ)的進(jìn)程知識(shí),之后會(huì)有更加深入的章節(jié),介紹進(jìn)程管理的相關(guān)源碼。
本節(jié)就到這里。
作者:CangWang
鏈接:https://www.jianshu.com/p/a525932db11c
來(lái)源:簡(jiǎn)書
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。
總結(jié)
以上是生活随笔為你收集整理的[Android]你不知道的Android进程化(3)--进程等级的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: replugin源码解析之replugi
- 下一篇: [Android]你不知道的Androi