做為應用開發者,對於進程生命周期和進程中的內存回收是透明的,但了解生命周期對加深對Andorid體系的理解很有幫助
一、 進程生命周期
Android系統將盡量長時間地保持應用進程,但為了新建進程或運行更重要的進程,最終需要清除舊進程來回收內存。 為了確定保留或終止哪些進程,系統會根據進程中正在運行的組件以及這些組件的狀態,將每個進程放入“重要性層次結構”中。 必要時,系統會首先消除重要性最低的進程,然後是清除重要性稍低一級的進程,依此類推,以回收系統資源。
進程的重要性,劃分5級:
- 前台進程(Foreground process)
- 可見進程(Visible process)
- 服務進程(Service process)
- 後台進程(Background process)
- 空進程(Empty process)
前台進程的重要性最高,依次遞減,空進程的重要性最低,下面分別來闡述每種級別的進程
1.1 Foreground process
用戶當前操作所必需的進程。通常在任意給定時間前台進程都為數不多。只有在內存不足以支持它們同時繼續運行這一萬不得已的情況下,系統才會終止它們。
- 擁有用戶正在交互的 Activity(已調用onResume())
- 擁有某個 Service,後者綁定到用戶正在交互的 Activity
- 擁有正在“前台”運行的 Service(服務已調用 startForeground())
- 擁有正執行一個生命周期回調的 Service(onCreate()、onStart() 或 onDestroy())
- 擁有正執行其 onReceive() 方法的 BroadcastReceiver
1.2 Visible process
沒有任何前台組件、但仍會影響用戶在屏幕上所見內容的進程。可見進程被視為是極其重要的進程,除非為了維持所有前台進程同時運行而必須終止,否則系統不會終止這些進程。
- 擁有不在前台、但仍對用戶可見的 Activity(已調用onPause())。
- 擁有綁定到可見(或前台)Activity 的 Service
1.3 Service process
盡管服務進程與用戶所見內容沒有直接關聯,但是它們通常在執行一些用戶關心的操作(例如,在後台播放音樂或從網絡下載數據)。因此,除非內存不足以維持所有前台進程和可見進程同時運行,否則系統會讓服務進程保持運行狀態。
- 正在運行startService()方法啟動的服務,且不屬於上述兩個更高類別進程的進程。
1.4 Background process
後台進程對用戶體驗沒有直接影響,系統可能隨時終止它們,以回收內存供前台進程、可見進程或服務進程使用。 通常會有很多後台進程在運行,因此它們會保存在LRU列表中,以確保包含用戶最近查看的Activity的進程最後一個被終止。如果某個 Activity 正確實現了生命周期方法,並保存了其當前狀態,則終止其進程不會對用戶體驗產生明顯影響,因為當用戶導航回該 Activity 時,Activity 會恢復其所有可見狀態。
- 對用戶不可見的Activity的進程(已調用Activity的onStop()方法)
1.5 Empty process
保留這種進程的的唯一目的是用作緩存,以縮短下次在其中運行組件所需的啟動時間。 為使總體系統資源在進程緩存和底層內核緩存之間保持平衡,系統往往會終止這些進程。
二、 Lowmemorykiller
Android中對於內存的回收,主要依靠Lowmemorykiller來完成,是一種根據阈值級別觸發相應力度的內存回收的機制。
2.1 ADJ級別
定義在ProcessList.java文件,oom_adj劃分為16級,從-17到16之間取值。
ADJ級別 |
取值 |
解釋 |
UNKNOWN_ADJ
16
一般指將要會緩存進程,無法獲取確定值
CACHED_APP_MAX_ADJ
15
不可見進程的adj最大值 1
CACHED_APP_MIN_ADJ
9
不可見進程的adj最小值 2
SERVICE_B_AD
8
B List中的Service(較老的、使用可能性更小)
PREVIOUS_APP_ADJ
7
上一個App的進程(往往通過按返回鍵)
HOME_APP_ADJ
6
Home進程
SERVICE_ADJ
5
服務進程(Service process)
HEAVY_WEIGHT_APP_ADJ
4
後台的重量級進程,system/rootdir/init.rc文件中設置
BACKUP_APP_ADJ
3
備份進程 3
PERCEPTIBLE_APP_ADJ
2
可感知進程,比如後台音樂播放 4
VISIBLE_APP_ADJ
1
可見進程(Visible process) 5
FOREGROUND_APP_ADJ
0
前台進程(Foreground process) 6
PERSISTENT_SERVICE_ADJ
-11
關聯著系統或persistent進程
PERSISTENT_PROC_ADJ
-12
系統persistent進程,比如telephony
SYSTEM_ADJ
-16
系統進程
NATIVE_ADJ
-17
native進程(不被系統管理)
2.2 進程state級別
定義在ActivityManager.java文件,process_state劃分18類,從-1到16之間取值。
state級別 |
取值 |
解釋 |
PROCESS_STATE_CACHED_EMPTY
16
進程處於cached狀態,且為空進程
PROCESS_STATE_CACHED_ACTIVITY_CLIENT
15
進程處於cached狀態,且為另一個cached進程(內含Activity)的client進程
PROCESS_STATE_CACHED_ACTIVITY
14
進程處於cached狀態,且內含Activity
PROCESS_STATE_LAST_ACTIVITY
13
後台進程,且擁有上一次顯示的Activity
PROCESS_STATE_HOME
12
後台進程,且擁有home Activity
PROCESS_STATE_RECEIVER
11
後台進程,且正在運行receiver
PROCESS_STATE_SERVICE
10
後台進程,且正在運行service
PROCESS_STATE_HEAVY_WEIGHT
9
後台進程,但無法執行restore,因此盡量避免kill該進程
PROCESS_STATE_BACKUP
8
後台進程,正在運行backup/restore操作
PROCESS_STATE_IMPORTANT_BACKGROUND
7
對用戶很重要的進程,用戶不可感知其存在
PROCESS_STATE_IMPORTANT_FOREGROUND
6
對用戶很重要的進程,用戶可感知其存在
PROCESS_STATE_TOP_SLEEPING
5
與PROCESS_STATE_TOP一樣,但此時設備正處於休眠狀態
PROCESS_STATE_FOREGROUND_SERVICE
4
擁有給一個前台Service
PROCESS_STATE_BOUND_FOREGROUND_SERVICE
3
擁有給一個前台Service,且由系統綁定
PROCESS_STATE_TOP
2
擁有當前用戶可見的top Activity
PROCESS_STATE_PERSISTENT_UI
1
persistent系統進程,並正在執行UI操作
PROCESS_STATE_PERSISTENT
0
persistent系統進程
PROCESS_STATE_NONEXISTENT
-1
不存在的進程
2.3 lmk策略
Lowmemorykiller根據當前可用內存情況來進行進程釋放,總設計了6個級別,即上表中“解釋列”加粗的行,即Lowmemorykiller的殺進程的6檔,如下:
- CACHED_APP_MAX_ADJ
- CACHED_APP_MIN_ADJ
- BACKUP_APP_ADJ
- PERCEPTIBLE_APP_ADJ
- VISIBLE_APP_ADJ
- FOREGROUND_APP_ADJ
系統內存從很寬裕到不足,Lowmemorykiller也會相應地從CACHED_APP_MAX_ADJ(第1檔)開始殺進程,如果內存還不足,那麼會殺CACHED_APP_MIN_ADJ(第2檔),不斷深入,直到滿足內存阈值條件。