記憶體不足時Android 系統如何Kill程序
大家其實都或多或少知道,Android系統有自已的工作管理員,當系統記憶體不足時,系統需要KILL一些程序(應用),以回收一部分資源,來保證系統仍可以正常的執行,而不會崩潰,今天,就具體講講這個原理。
程序優先順序(importance hierarchy)
Android系統儘量保持程序執行的更久,但是仍有時候,需要結束掉老的程序,回收記憶體來保證新的,或更重要的程序執行。要決定哪些程序執行,哪些被 KILL,系統會為每個執行的程序或者元件設定其程序優先順序。通常KILL的順序是優先順序最低,然後其次,等等依次這樣下去。
一共有五級:
前臺程序(Foreground Process)
滿足以下條件即為前臺程序:
a. 使用者當前正在操作的Activity(Activity.onResume方法已經被呼叫了);
b. Service繫結到使用者當前正在操作的Activity;
c. Service在前臺執行(Service.startForeground);
d. Service正在執行生命週期中的方法之一(onCreate, onStart, onDestroy);
e. BroadcastReceiver正在執行onReceive方法;
通常,前臺程序是很少的(就以上幾種),所以它們是最後被KILL的(記憶體極少,系統為了能保證正常執行,且能與使用者互動,當前臺程序不止一個時,會KILL某些前臺程序)。不過,這情況,對於目前的手機來說,不太可能發生的事。
可見程序(Visible process)
滿足以下條件即為可見程序:
a. Activity不為前臺程序,但生命週期處於onPause狀態,也就是說,一個Dialog擋住了部分Activity;
b. 和1.b中一樣,Service繫結在當前可見或前臺Activity;
可見程序同樣也很重要,當系統記憶體不足,且為了保證前臺程序繼續執行時,可見程序會被KILL掉。
服務程序(Service process)
通常都是被startService方法呼叫而執行的Service,而沒有繫結到其它Activity上(即1.b, 2.b中所說的情況),這些Service可能是在後臺下載,或是類似音樂播放器一樣等服務,同樣,為了保證前臺和可見程序能夠正常執行,系統會KILL 掉服務程序。
後臺程序(Background process)
這些程序通常都是Activity完全不可見,即生命週期處於onStop階段時,只要不影響到使用者的操作,那麼,就可以隨時被系統KILL掉用來保證前臺,可見或是服務程序的執行。通常,有很多後臺程序在執行,系統會將它們放入到LRU(Last Recent Used,最近使用)列表中,用來決定:最近使用過的最後被KILL,而很長時間沒使用過的,將會被第一個KILL掉。
空程序(Empty process)
這類程序沒有任何活動應用,之所有會有這樣的程序,是為了快取的目的。為了加快某個元件下次啟動的時間而設計的。系統經常KILL這些程序用來平衡整個系統資源(通常是在程序快取和核心快取之間做平衡)。
總結:
i) 系統會根據程序的不同狀態,會動態調整程序的優先順序,比如:使用者當前與某個Activity互動,然後按了一下HOME鍵,則程序從前臺程序切換至後臺程序,並被加入到LRU列表中;
ii) 程序所處不同的優先順序,將會決定當系統記憶體不足時,其命運將會如何,程序被KILL的順序上面已經說的很清楚了,我這裡再羅列下(空程序不考慮):
— 後臺程序 -> 服務程序 -> 可見程序 -> 前臺程序;
後臺程序又以LRU來決定:
— LRU中找到最長時間沒用過的先被KILL,然後找到其次最長時間沒用過的被KILL,依次類推,而最近被使用過的最後KILL。