Android 系統程序間的關係
概括
系統啟動架構圖:
本文是從程序/執行緒的視角來分析該問題。
1.1 父程序
在所有程序中,以父程序的姿態存在的程序(即圖中的淺紅色項),如下:
- kthreadd程序: 是所有核心程序的父程序
- init程序 : 是所有使用者程序的父程序(或者父父程序)
- zygote程序 : 是所有上層Java程序的父程序,另外zygote的父程序是init程序。
1.2 重量級程序
在Android程序中,有3個非常重要的程序(即圖中的深紫色項),如下:
- system_server:是由zygote孵化而來的,是zygote的首席大弟子,托起整個Java framework的所有service,比如ActivityManagerService, PowerManagerService等等。
- mediaserver:是由init孵化而來的,托起整個C++ framework的所有service,比如AudioFlinger, MediaPlayerService等等。
- servicemanager:是由init孵化而來的,是整個Binder架構(IPC)的大管家,所有大大小小的service都需要先請示servicemanager。
程序
Android程序從大類來劃分,可分為核心程序和使用者程序。
2.1 kthreadd子程序
kthreadd程序(2號程序),是Linux系統的核心程序,是所有核心程序的鼻祖。
由Kthreadd孵化出來的核心守護程序,這些程序位於系統啟動架構圖中的kernel的深藍色塊。下面列舉常見的核心程序:
程序 | 備註 |
---|---|
ksoftirqd/0 | |
kworkder/0:0H | |
migration/0 | |
watchdog/0 | |
binder | |
rcu_sched | |
perf | |
netns | |
rpm-smd | |
mpm | |
writeback | |
system | |
irq/261-msm_iom | |
mdss_dsi_event | |
kgsl-events | |
spi | |
therm_core:noti | |
msm_thermal:hot | |
… |
核心程序都不存在子程序與子執行緒,並且所有核心程序的使用者都是root.
每個核心程序的作用,後續再補上
2.2 init子程序
init程序(1號程序),是Linux系統的使用者空間程序,或者說是Android的第一個使用者空間程序。
下面列舉常見的由init程序孵化而來的使用者程序:
程序 | 程序檔案 | 備註 |
---|---|---|
zygote | /system/bin/app_process | Java界的第一個程序,分32位和64位 |
servicemanager | /system/bin/servicemanager | Binder的守護程序 |
mediaserver | /system/bin/mediaserver | 多媒體服務的程序 |
healthd | /sbin/healthd | 電池的守護程序 |
surfaceflinger | /system/bin/surfaceflinger | UI幀相關的程序 |
logd | /system/bin/logd | log的守護程序 |
…… |
servicemanager,作為Binder架構的一個大管家,所有註冊服務、獲取服務,都需要經過servicemanager
2.3 Zygote子程序
Zygote本身是一個Native的應用程式,剛開始的名字為“app_process”,執行過程中,通過系統呼叫將自己名字改為Zygote。是所有上層Java程序的父程序,android系統中還有另一個Zygote64程序,用於孵化64位的應用程序。
在圖中的紅色線,便是Zygote fork出來的程序,所有的App程序都是由Zygote fork產生的。
下面列舉Zyogte程序孵化的部分子程序:
程序 | 備註 |
---|---|
system_server | Java framework的各種services都依賴此程序 |
android.process.media | 多媒體應用程序 |
com.android.settings | 設定程序 |
com.android.wifi | Wifi應用程序 |
com.android.phone | 電話應用程序 |
…… |
執行緒
3.1 Zygote 子執行緒
在adb shell終端,輸入:
ps -t | grep -E "NAME| 497 "
解釋: -E “NAME| 497 ” 是輸出時能多顯示NAME的那一行,方便檢視每一列代表的具體含義,497是Zygote的程序號。
共享父程序的地址空間的便是子執行緒,即VSIZE必然相同,否則就是子程序,如下圖:
圖中紅色圈起來的便是子執行緒,其他都是子程序。
可見Zygote的子執行緒如下:
程序 | 備註 |
---|---|
ReferenceQueueD | 引用佇列的守護執行緒 |
FinalizerDaemon | 析構的守護執行緒 |
FinalizerWatchd | 析構監控的守護執行緒 |
HeapTrimmerDaem | 堆整理的守護執行緒 |
GCDaemon | 執行GC的守護執行緒 |
這5個執行緒都是與虛擬機器息息相關的執行緒,之後所有由Zygote直接或間接孵化的子程序,都會包含這5個執行緒,那麼就在其執行緒說明中,不再重複,而是以“用於GC”的字樣來表示。
3.2 system_server 子執行緒
Java Framework中的service都執行在system_server程序中,system_server內的子執行緒很多,統計了下自己身邊的手機有system_server有122個執行緒。下面列舉部分子執行緒:
程序 | 備註 |
---|---|
system_server | 包含4個此同名執行緒 |
Heap thread poo | 非同步的HeapWorker, 包含5個 |
Signal Catcher | 捕捉Kernel訊號,比如SIGNAL_QUIT |
JDWP | 虛擬機器除錯的執行緒 |
ReferenceQueueD | 用於GC |
FinalizerDaemon | 用於GC |
FinalizerWatchd | 用於GC |
HeapTrimmerDaem | 用於GC |
GCDaemon | 用於GC |
Binder_ | IPC執行緒, 包含16個 |
Thread_ | 普通執行緒,包含若干個 |
AsyncTask # | 非同步任務,包含若干個 |
RenderThread | 渲染執行緒,可以包含若干個 |
ActivityManager | ActivityManagerService執行緒 |
PerformanaceCont | system_server專有 |
FileObserver | system_server專有 |
CpuTracker | 統計程序CPU資訊 |
PowerManagerSer | system_server專有 |
PackageManager | system_server專有 |
watchdog | system_server專有 |
WifiMonitor | system_server專有 |
UEventObserver | system_server專有 |
… | … |
ActivityManagerService執行緒是一個ServerThread執行緒。程序結構體task_struct的comm欄位是一個長度為16的char型,故程序名最長為15個字元。
3.3 mediaserver 子執行緒
mediaserver 子執行緒,如下:
執行緒名 | 備註 |
---|---|
mediaserver | |
ApmTone | |
ApmAudio | |
ApmOutput | |
Safe Speaker Th | |
AudioOut_2 | |
FastMixer | |
AudioOut_4 | |
FastMixer | |
AudioOut_6 | |
Binder_1 | |
Binder_2 |
3.4 app 子執行緒
此處以settings為例
執行緒名 | 備註 |
---|---|
com.android.settings | settings程序 |
Heap thread poo | 非同步的HeapWorker, 包含5個 |
Signal Catcher | 捕捉Kernel訊號,比如SIGNAL_QUIT |
JDWP | 虛擬機器除錯的執行緒 |
ReferenceQueueD | 用於GC |
FinalizerDaemon | 用於GC |
FinalizerWatchd | 用於GC |
HeapTrimmerDaem | 用於GC |
GCDaemon | 用於GC |
Binder_1 | 用於IPC |
Binder_2 | 用於IPC |
pool-m-thread-n | 執行緒池m中的第n個執行緒,包含若干個 |
AsyncTask #1 | 異常任務 |
RenderThread | 會有若干個 |
WifiManager | 管理wifi的執行緒 |
一般地,每個apk都會產生2或3個Binder執行緒,Apk執行的Activity或service都會產生2個Binder執行緒。
關於Binder問題
主執行緒是由 Zygote母體生成的;
執行緒池:首次建立第一個Binder執行緒A,然後監聽BR_SPAWN_LOOPER事件,收到後建立第二個Binder執行緒B,執行緒B繼續監聽BR_SPAWN_LOOPER事件,收到後建立第三個Binder執行緒C。總共建立3個Bindr執行緒,這是Binder協議決定。根據系統處理器數目以及應用程式的負載強度,執行緒池的執行緒數目可以動態調整,這是Binder優化需要考慮的。