從調度角度看
Android進程/線程的調度基於Linux OS的調度,並使用了Linux提供的cgroup對進程進行分組管理。4.4.2版本系統提供了3個cpu cgroup分組:
SYSTEM、FOREGROUND和BACKGROUND,
3個cpu cgroup分組有層次關係,依次爲父子關係。對應的cgroup目錄如下:
/dev/cpuctl/tasks
/dev/cpuctl/apps/tasks
/dev/cpuctl/apps/bg_non_interactive/tasks
對外接口上提供5個調度策略類別:
SYSTEM、AUDIO_APP 、AUDIO_SYS 、FOREGROUND和BACKGROUND
前面3個類別在實現上目前納入都到SYSTEM對應的cgroup分組
Android爲什麼使用了cgroup?
通過搜索學習,發現一種比較靠譜的解釋,總結下就是:Android系統天生存在前後臺的概念(有屏幕,可見的APP可以理解爲前提APP,其他爲後臺),cgroup的增加就是爲了前臺APP流暢運行提供保證的。結合init.rc可以有比較直觀的理解,
write /dev/cpuctl/apps/cpu.shares1024
write /dev/cpuctl/apps/cpu.rt_runtime_us800000
write /dev/cpuctl/apps/cpu.rt_period_us1000000
# 5.0 %
write /dev/cpuctl/apps/bg_non_interactive/cpu.shares52
write /dev/cpuctl/apps/bg_non_interactive/cpu.rt_runtime_us700000
write /dev/cpuctl/apps/bg_non_interactive/cpu.rt_period_us1000000
從cpu.share可以看出,Android給後臺APP分配的競爭cpu爲52,約前臺APP的5%。
另外還有1個根cgroup,是給系統進程服務的,配置跟前臺APP類似,但在實時處理上優於前臺APP。
write /dev/cpuctl/cpu.shares1024
write /dev/cpuctl/cpu.rt_runtime_us950000
write /dev/cpuctl/cpu.rt_period_us1000000
Android的APK的工作時,除了UI主線程被加入前臺APP cgroup組,其他的線程都被放入後臺APP cgroup。
從進程回收角度看
相關資料一般講Android將進程分爲6個等級,它們按優先級順序由高到低依次是:
1.前臺進程( FOREGROUND_APP)
2.可視進程(VISIBLE_APP )
3.次要服務進程(SECONDARY_SERVER )
4.後臺進程 (HIDDEN_APP)
5.內容供應節點(CONTENT_PROVIDER)
6.空進程(EMPTY_APP)
這裏的優先級是指進程在系統中存在的優先級,也有講5個級別,刨去5內容供應(CONTENT_PROVIDER)。在4.4.2源碼中給出了很多級別,存在優先級高到低(被omm-killer選擇殺掉優先級由低到高)等級依次爲:
NATIVE_ADJ = -17
SYSTEM_ADJ = -16
PERSISTENT_PROC_ADJ = -12
FOREGROUND_APP_ADJ = 0
VISIBLE_APP_ADJ = 1
PERCEPTIBLE_APP_ADJ = 2
BACKUP_APP_ADJ = 3
HEAVY_WEIGHT_APP_ADJ = 4
SERVICE_ADJ = 5
HOME_APP_ADJ = 6
PREVIOUS_APP_ADJ = 7
SERVICE_B_ADJ = 8
CACHED_APP_MIN_ADJ = 9
CACHED_APP_MAX_ADJ = 15
UNKNOWN_ADJ = 16
從對應關係上來看,網上查詢資料所講的進程級別是對於app來講的。APP進程等級確定原則:
1.如果一個進程裏面同時包含service和可視的activity,那麼這個進程應該歸於可視進程,而不是service進程.
2.另外,如果其他進程依賴於它的話,一個進程的等級可以提高.例如,一個A進程裏的service被綁定到B進程裏的組件上,進程A將總被認爲至少和B進程一樣重要.
3.系統中的phone服務被劃分到前臺進程而不是次要服務進程.
在android中以進程的oom_adj值也就代表了它的優先級.
oom_adj值越高代表該進程優先級越低。在init.rc中爲系統首進程1賦予了-16:
write /proc/1/oom_adj -16
如此,從繼承的角度,系統中沒有比root更高優先級的。
進程oom_adj值的更新:
android進程的oom_adj都在ActivityManagerService中更新
1 2 3 4 |
updateOomAdjLocked() => int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP, false); Process.setOomAdj(app.pid, adj) => android_os_Process_setOomAdj //android_util_Process.cpp |
Android的工作策略:爲保證APP的流暢運行,系統一般不主動殺掉不活動的APP,以便下次啓動或運行時得到快速執行。