Android進程管理機制小結(jié)

一:概念
1 進程概念
每個App在啟動前必須先創(chuàng)建一個進程,該進程是由Zygote fork出來的,進程具有獨立的資源空間,用于承載App上運行的各種Activity/Service等組件。

2 同一個應(yīng)用定義多進程的方式
大多數(shù)情況一個App就運行在一個進程中,除非在AndroidManifest.xml中配置Android:process屬性,或通過native代碼fork進程。

3 分類
Android中的進程分為用戶進程和內(nèi)核進程。
kthreadd進程:所有內(nèi)核進程的父進程。
init進程:所有用戶進程的父進程。
其中用戶進程中的幾個重要進程:
zygote進程:是上層所有java進程的父進程。由init進程fork而來。
system_server進程:承載java層framwork的所有serveices進程,由zygote進程fork而來。
mediaserver進程:托起整個c++ framework的所有service進程,有init進程孵化而來。
servicemanager進程:管理整個Binder架構(gòu), 由init進程孵化而來。

4 android進程間通信的方式
4.1 Binder
activity啟動Activity,啟動Service,ContentProvider的本質(zhì)都是Binder進程間通信機制。AIDL也是IPC機制的一種實現(xiàn),本質(zhì)也是通過Binder去實現(xiàn)的。
4.2 Socket
創(chuàng)建一個Process的時候,是通過system_server進程調(diào)用Process.start()方法請求Zygote進程去創(chuàng)建進程的,這種方式是通過Socket去完成的。

二:進程管理機制
1 App啟動內(nèi)存機制:
Android系統(tǒng)的設(shè)計理念正是希望應(yīng)用進程能盡量長時間地存活,以提升用戶體驗。應(yīng)用首次打開比較慢,這個過程有進程創(chuàng)建以及Application等信息的初始化,所以應(yīng)用在啟動之后,即便退到后臺并非立刻殺死,而是存活一段時間,這樣下次再使用則會非常快。
2 LMK策略:
為了防止剩余內(nèi)存過低,Android在內(nèi)核空間有LowMemoryKiller(簡稱LMK),是一種根據(jù)閾值級別觸發(fā)相應(yīng)力度的內(nèi)存回收的機制。其依據(jù)就是進程優(yōu)先級的量化指標:ADJ值。
ADJ值定義在ProcessList.java中。
從Android 7.0開始,ADJ采用100、200、300;在這之前的版本ADJ采用數(shù)字1、2、3,這樣的調(diào)整可以更進一步地細化進程的優(yōu)先級,比如在VISIBLE_APP_ADJ(100)與PERCEPTIBLE_APP_ADJ(200)之間,可以有ADJ=101、102級別的進程。
下表列出了進程adj值對應(yīng)的情景:


image.png

3 查看進程ADJ值的方法:
3.1
cat /proc/[PID]/oom_adj: 使用該命令會直接顯示出對應(yīng)進程號的adj值,這種方式在Android N以后會因為權(quán)限問題無法查看
cat /proc/[PID]/oom_score,查看計算出的優(yōu)先級值,這種方式在O上仍然可以用
3.2
dumpsys meminfo
使用dumpsys meminfo命令時,會列出當前系統(tǒng)的所有進程,不同進程放入不同的分類,對應(yīng)的分類名基本與lmk的分類一致。

4 進程保護策略
4.1 開啟一個像素的Activity
據(jù)說這個是手Q的進程保活方案,基本思想,系統(tǒng)一般是不會殺死前臺進程的。所以要使得進程常駐,我們只需要在鎖屏的時候在本進程開啟一個Activity,為了欺騙用戶,讓這個Activity的大小是1像素,并且透明無切換動畫,在開屏幕的時候,把這個Activity關(guān)閉掉,所以這個就需要監(jiān)聽系統(tǒng)鎖屏廣播

4.2 前臺服務(wù)
這種大部分人都了解,據(jù)說這個微信也用過的進程保活方案,這方案實際利用了Android前臺service的漏洞。
原理如下
對于 API level < 18 :調(diào)用startForeground(ID, new Notification()),發(fā)送空的Notification ,圖標則不會顯示。
對于 API level >= 18:在需要提優(yōu)先級的service A啟動一個InnerService,兩個服務(wù)同時startForeground,且綁定同樣的 ID。Stop 掉InnerService ,這樣通知欄圖標即被移除。
無論是QQ還是微信的進程保活策略都是通過提高進程優(yōu)先級,降低adj的方式去實現(xiàn),但是除非廠商愿意將你的應(yīng)用加入清理白名單,否則在app層面是無法做到真正的進程不死,只能是盡量保證進程不被kill。

5 Kill進程的方式
5.1 Process.killProcess(pid)方式
Process.killProcessQuiet(pid)
用戶空間流程:
Process.killProcess()-->Process.sendSignal()-->
android_util_Process. android_os_Process_sendSignal()-->kill()
注意:
kill()之后就進入內(nèi)核空間調(diào)用的是內(nèi)核的相關(guān)方法去完成殺進程的操作。
另外需要注意的調(diào)用這種方式殺進程,如果進程中有服務(wù)是在被殺掉以后重啟的,那么是需要重啟進程的,意思是說這種方式針對有這種服務(wù)的進程相當于先殺死在啟動的,重啟一下而已(在Log中會看到類似Scheduling restart of crashed service的信息)。

5.2 Force-stop方式:
AM.forceStopPackage(packageName) 這個是隱藏api,并且需要force-stop系統(tǒng)級權(quán)限
流程:
1)AMS.forceStopPackage(final String packageName, int userId);
2)AMS.forceStopPackage()-->
AMS.finishForceStopPackageLocked()
3)AMS.forceStopPackageLocked()-->
4)AMS.forceStopPackageLocked(9參的)
注意:
1)force-stop并不會殺persistent進程,當指定用戶userId時,不殺其他用戶空間的進程。
2)當app被force-stop后,無法接收到任何普通廣播,那么也就常見的監(jiān)聽手機網(wǎng)絡(luò)狀態(tài)的變化或者屏幕亮滅的廣播來拉起進程肯定是不可行;
3)當app被force-stop后,那么alarm鬧鐘一并被清理,無法實現(xiàn)定時響起的功能;
4)app被force-stop后,四大組件以及相關(guān)進程都被一一剪除清理,即便多進程架構(gòu)的app也無法拉起自己;
5)級聯(lián)誅殺:當app通過ClassLoader加載另一個app(在后一個app的ProcessRecord的pkgDeps中會有前一個app的包名信息,則殺掉后一個app,前一個app也會被干掉),則會在force-stop的過程中會被級聯(lián)誅殺;
6)生死與共:當app與另個app使用了share uid,則會在force-stop的過程,任意一方被殺則另一方也被殺,建立起生死與共的強關(guān)系。

5.3 killBackgroundProcesses方式
流程:
AM.killBackgroundProcesses(String packageName)
--> AMS.killBackgroundProcesses(final String packageName, int userId)
--> killPackageProcessesLocked();
同樣會調(diào)用到killPackageProcessesLocked方法殺進程,只不過入?yún)dj的設(shè)定值是ProcessList.SERVICE_ADJ即500,進程Adj值大于這個才會執(zhí)行后續(xù)殺進程方法,否則continue。這個方法需要添加權(quán)限KILL_BACKGROUND_PROCESSES(不是系統(tǒng)權(quán)限)。

5.4 adb shell中執(zhí)行 kill +pid的命令殺進程,這種方式最后也是調(diào)用的Process. killProcess()方法殺進程。但是沒有killing 相關(guān)的log打印出。這種方式需要root權(quán)限。

5.5 adb shell am force-stop +包名。這種方式會調(diào)用到AMS的forceStopPackage方法,因此會有相應(yīng)log打出,需要root權(quán)限。
若使用Runtime去執(zhí)行的話,也是需要force-stop權(quán)限的,系統(tǒng)級權(quán)限。

參考文檔:https://gityuan.com/2018/05/19/android-process-adj/

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,428評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,024評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,285評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,548評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,328評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,878評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,971評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,098評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,616評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,554評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,725評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,243評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 43,971評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,361評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,613評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,339評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,695評論 2 370

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,582評論 25 707
  • 用兩張圖告訴你,為什么你的 App 會卡頓? - Android - 掘金 Cover 有什么料? 從這篇文章中你...
    hw1212閱讀 12,765評論 2 59
  • 本篇文章是后臺殺死系列的最后一篇,主要探討一下進程的保活,Android本身設(shè)計的時候是非常善良的,它希望進程在不...
    看書的小蝸牛閱讀 11,711評論 10 66
  • 如何進行進程保活,首先我們應(yīng)該先分析一下進程被殺死的原因開始 Android進程被殺死的場景分析: 從 Andro...
    如穎隨行日記閱讀 4,927評論 2 4
  • 一. 目的: 知道在某種場景下該使用何種居中。 二. 內(nèi)容 1. 簡單的水平居中 1.1 text-align: ...
    遠山黛子閱讀 310評論 0 1