如果對fork機制不瞭解的,可以先看看本部落格的從一道面試題談linux下fork的運行機制
這篇文章
jollen
發表於 April 5, 2010 3:14 PM
Android 作業系統開機時,會經由 init.rc 來啟動許多外部程式,其中有一個最重要 process 稱為 Zygote。Zygote 是 Android 的 monitor process,它主要負責二項工作:
1. 啟動 system server
2. 執行 Android 應用程式
「System Server」是由 Zygote 所建立的另外一個 process,建立 system server 的方式是使用典型的
Linux system call - fork()。當 Zygote 成功建立 system server 後,便進入 socket
listening 模式。在此模式下,zygote 會監聽(listen)由 socket 所傳入的「命令」,並依據命令的內容啟動
Android 應用程式。
Zygote 啟動外部 Android 應用程式的方式,同樣是使用 Linux kernel 所提供的 fork() system
call。因此,在 socket 做 listening,並依據命令來 fork() 並執行外部 Android 應用程式,稱之為「Zygote
Mode」。
android的系統應用中的一個重要的進程就是zygote,所有的java應用程式進程都是由zygote派生出來的,zygote這個進程的作用就
是“生兒子”。具體的一個應用如何出來的大家可以看我以前的一篇文章-----Android 應用初始化及表單事件的分發。
首先要瞭解一點初始化語言的基本知識吧:
Services(服務)是一個程式,他在初始化時啟動,並在退出時重啟(可選)。Services(服務)的形式如下:
service <name> <pathname> [ <argument> ]*
<option>
<option>
Options為選項,具體可以參考linux service命令
zygote進程正是在linux kernel startup後通過這個檔案啟動的,具體看init.rc中這一段:
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
socket zygote stream 666
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
一段一段的分析這個代碼:
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
啟動服務名字zygote. /system/bin/app_process 進程的bin檔案具體路徑,後面跟的就是啟動參數-Xzygote /system/bin --zygote
--start-system-server
。這段參數有什麼作用可以對照看代碼app_main.cpp
if (i < argc) {
arg = argv[i++];
if (0 == strcmp("--zygote
", arg)) {
bool startSystemServer = (i < argc) ?
strcmp(argv[i], "--
start-system-server
") == 0 : false;
setArgv0(argv0, "zygote");
set_process_name("zygote");
runtime.start
("com.android.internal.os.ZygoteInit",
startSystemServer);
} else {
set_process_name(argv0);
runtime.mClassName = arg;
// Remainder of args get passed to startup class main()
runtime.mArgC = argc-i;
runtime.mArgV = argv+i;
LOGV("App process is starting with pid=%d, class=%s./n",
getpid(), runtime.getClassName());
runtime.start();
}
}
-Xzygote
這個參數的意義是在jvm中設定gDvm.zygote = true;至於這個參數的具體作用大家自己看代碼吧。 其流程是
androidRuntime->start() call---> JNI_CreateJavaVM() call
---->dvmStartup()(戴維林虛擬機器初始化) call---->dvmProcessOptions().
/system/bin :也許是告知系統應用的路徑吧,大家看到了告訴我。
onrestart write /sys/android_power/request_state wake:
如果這個服務重啟了,開啟/sys/android_power/request_state 這個檔案寫入wake字串。
Zygote Service
在本章我們會接觸到這兩個單詞:
•Zygote [生物] 受精卵, 接合子, 接合體
•Spawn:產卵
通過這兩個單詞,我們就可以大體知道Zygote是幹什
麼的了,就是叫老母雞下蛋。通過“Zygote”產出不同的子“Zygote”。從大的架構上講,Zygote是一個簡單的典型C/S結構。其他進程作為
一個客服端向Zygote發出”孵化”請求,Zygote接收到命令就“孵化”出一個Activity進程來。
Zygote系統程式碼群組成及其調用結構:
•Zygote.java
提供訪問Dalvik “zygote”的介面。主要是封裝Linux系統的Fork,以建立一個新的VM執行個體進程。
•ZygoteConnection.java
Zygote的套介面串連管理及其參數解析。其他Actvitiy建立進程請求是通過套介面發送命令參數給Zygote。
•ZygoteInit.java
Zygote的main函數入口。
Zygote系統代碼層次調用
main()
Startsystemserver()…
RunSelectLoopMode()
Accept socket connection
Conntecion.RunOnce()
Read argument
folkAndSpecialize
folkAndSpecialize使用Native函數Dalvik_dalvik_system_Zygote_forkAndSpecialize
//native 的擷取
dalvik/vm/native
//dalvik_system_Zygote.c
const DalvikNativeMethod dvm_dalvik_system_Zygote[] = {
{ "fork", "()I",
Dalvik_dalvik_system_Zygote_fork },
{ "forkAndSpecialize", "(II[II[[I)I",
Dalvik_dalvik_system_Zygote_forkAndSpecialize },
{ "forkSystemServer", "(II[II[[I)I",
Dalvik_dalvik_system_Zygote_forkSystemServer },
{ NULL, NULL, NULL },
};
在這裡我們就有了Zygote服務的全貌理解,也在Code中印證了,Activity在本質上是個什麼東西,就是一個Linux進程。但
是不是一個簡單的Linux進程,畢竟Activity是在Andoid概念空間中才有效。在這個概念空間中,Activity被封裝,在螢幕上呈現
UI,使用者看到的整個螢幕或者一個視窗,對於機器來講,呈現在使用者面前的就叫Actvitiy。從分析中我們可以看到,Android使用了Linux的
fork機制。在Linux中Fork是很高效的。
一個Android的Activity實際上一個Linux進程,所謂進程具備下面幾個要素,
a.要有一段程式供該進程運行,程式是可以被多個進程共用的。
b..進程專用的系統堆棧空間。
c.進程式控制制塊,在linux中具體實現是task_struct
d.有獨立的儲存空間。
fork
創造的子進程複製了父親進程的資源,包括記憶體的內容task_struct內容,在複製過程中,子進程複製了父進程的task_struct,系統堆棧空
間和頁面表,而當子進程改變了父進程的變數時候,會通過copy_on_write的手段為所涉及的頁面建立一個新的副本。所以只有子進程有改變變數時,
子進程才建立了一個頁面複製原來頁面的內容,基本資源的複製是必須的,整體看上去就像是父進程的隔離儲存區 (Isolated Storage)空間也複製了一遍。
再看看下面Google在講解Dalvik虛擬機器的圖片,我們就大體有了Android系統中Actvitiy的實際映射狀態有了基本的認識。
本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/maxleng/archive/2010/04/20/5508488.aspx