前言
前面分析了init流程的啟動(dòng),在解析init.rc配置文件中,會(huì)執(zhí)行start zygote,然后會(huì)去解析相關(guān)的init.zygote.rc文件,在init.rc文件的頂部的import可以看出,由于操作系統(tǒng)的兼容性,有純32位,純64位,也有兼容模式的64_32,這樣會(huì)產(chǎn)生兩個(gè)zygote進(jìn)程,分別用于去fork不同位數(shù)的用戶應(yīng)用。

接下來(lái)就開(kāi)始分析zygote進(jìn)程的流程,以64_32位的zygote為例子分析
//#init.zygote64_32.rc
/***
* 進(jìn)程名稱是 zygote
* 運(yùn)行的二進(jìn)制文件在 /system/bin/app_process64
* 啟動(dòng)參數(shù)是 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
**/
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
class main
priority -20
user root
group root readproc reserved_disk
socket zygote stream 660 root system //創(chuàng)建一個(gè) socket,名字叫zygote
socket usap_pool_primary stream 660 root system
onrestart exec_background - system system -- /system/bin/vdc volume abort_fuse
onrestart write /sys/power/state on //onrestart 指當(dāng)前進(jìn)程重啟時(shí)執(zhí)行后面的命令
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
onrestart restart wificond
task_profiles ProcessCapacityHigh MaxPerformance
service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary --enable-lazy-preload
class main
priority -20
user root
group root readproc reserved_disk
socket zygote_secondary stream 660 root system
socket usap_pool_secondary stream 660 root system
onrestart restart zygote
task_profiles ProcessCapacityHigh MaxPerformance
通過(guò)對(duì)應(yīng)Android.bp文件可知道,zygote進(jìn)程的啟動(dòng),會(huì)進(jìn)入到app_main.cpp代碼,執(zhí)行對(duì)應(yīng)的main函數(shù)
//#app_main.cpp
int main(int argc, char* const argv[])
{
// 將參數(shù) argv 放到 argv_String 字符串中,然后打印出來(lái)
// 之前start zygote 傳入的參數(shù)是 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
if (!LOG_NDEBUG) {
String8 argv_String;
for (int i = 0; i < argc; ++i) {
argv_String.append("\"");
argv_String.append(argv[I]);
argv_String.append("\" ");
}
ALOGV("app_process main with argv: %s", argv_String.string());
}
//AppRuntime 定義于 app_main.cpp 中,繼承自 AndroidRuntime
//就是對(duì) Android 運(yùn)行環(huán)境的一種抽象,類似于 Java 虛擬機(jī)對(duì) Java 程序的作用
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
// Process command line arguments
// ignore argv[0]
argc--;
argv++;
//這兩個(gè)參數(shù)是Java 程序需要依賴的jar包,相當(dāng)于import
const char* spaced_commands[] = { "-cp", "-classpath" };
bool known_command = false;
int I;
for (i = 0; i < argc; i++) { //解析參數(shù)的起點(diǎn)
if (known_command == true) { //將 space_commands 中的參數(shù)額外加入 VM
runtime.addOption(strdup(argv[i]));
known_command = false;
continue;
}
for (int j = 0;
j < static_cast<int>(sizeof(spaced_commands) / sizeof(spaced_commands[0]));
++j) {
//比較參數(shù)是否是 spaced_commands 中的參數(shù)
if (strcmp(argv[i], spaced_commands[j]) == 0) {
known_command = true;
}
}
//如果參數(shù)第一個(gè)字符是'-',直接跳出循環(huán),zygote啟動(dòng)的參數(shù)第一個(gè)參數(shù)就是 -Zygote,執(zhí)行到這里就會(huì)跳出循環(huán)
if (argv[i][0] != '-') {
break;
}
if (argv[i][1] == '-' && argv[i][2] == 0) {
++i; // Skip --.
break;
}
runtime.addOption(strdup(argv[i]));
}
// Parse runtime arguments. Stop at first unrecognized option.
//這里可以看出,通過(guò)app_main 可以啟動(dòng) zygote,system-server,普通的application進(jìn)程
bool zygote = false;
bool startSystemServer = false;
bool application = false;
String8 niceName; // app_process 的名稱改為 zygote
String8 className; // 啟動(dòng) apk 進(jìn)程時(shí),對(duì)應(yīng)的類名
++i; // Skip unused "parent dir" argument.
//跳過(guò)一個(gè)參數(shù),就是 -Xzygote 后面的參數(shù),也就是 、system/bin,就是所謂的parent dir
while (i < argc) { //開(kāi)始解析參數(shù)
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) { //表示是 zygote 啟動(dòng)模式
zygote = true;
niceName = ZYGOTE_NICE_NAME; //這個(gè)值就是根據(jù)平臺(tái)參數(shù),可能是zygote64 或者 zygote
} else if (strcmp(arg, "--start-system-server") == 0) {
startSystemServer = true; //init.zygote.rc 中定義,啟動(dòng)zygote 后會(huì)啟動(dòng) system-server
} else if (strcmp(arg, "--application") == 0) {
application = true; //表示是 application 啟動(dòng)模式,也就是普通的應(yīng)用程序
} else if (strncmp(arg, "--nice-name=", 12) == 0) {
niceName.setTo(arg + 12); // 進(jìn)程別名,可以自己知道進(jìn)程名
} else if (strncmp(arg, "--", 2) != 0) {
className.setTo(arg); // 與 --application 配置,啟動(dòng)指定的類,application 啟動(dòng)的class
break;
} else {
--I;
break;
}
}
//準(zhǔn)備參數(shù)
Vector<String8> args;
if (!className.isEmpty()) { //className 不為空,說(shuō)明是 application 啟動(dòng)模式
args.add(application ? String8("application") : String8("tool"));
runtime.setClassNameAndArgs(className, argc - i, argv + i);
if (!LOG_NDEBUG) {
String8 restOfArgs;
char* const* argv_new = argv + I;
int argc_new = argc - I;
for (int k = 0; k < argc_new; ++k) {
restOfArgs.append("\"");
restOfArgs.append(argv_new[k]);
restOfArgs.append("\" ");
}
ALOGV("Class name = %s, args = %s", className.string(), restOfArgs.string());
}
} else { // zygote 啟動(dòng)模式
// We're in zygote mode.
maybeCreateDalvikCache(); //創(chuàng)建dalvik 的緩存目錄并定義權(quán)限
if (startSystemServer) { //增加 start-system-server 參數(shù)
args.add(String8("start-system-server"));
}
char prop[PROP_VALUE_MAX]; //獲取對(duì)應(yīng)平臺(tái)的 abi 信息
if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) {
LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.",
ABI_LIST_PROPERTY);
return 11;
}
String8 abiFlag("--abi-list="); //參數(shù)需要指定 abi
abiFlag.append(prop);
args.add(abiFlag); // 加入 --abi-list = 參數(shù)
for (; i < argc; ++i) {
args.add(String8(argv[i])); //將剩下的參數(shù)加入 args
}
}
if (!niceName.isEmpty()) { //將 app_process 的進(jìn)程名,替換為niceName
runtime.setArgv0(niceName.string(), true /* setProcName */);
}
if (zygote) { //調(diào)用 Runtime 的start 函數(shù),啟動(dòng) zygoteInit
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {
//非zygote啟動(dòng)方式進(jìn)入這個(gè)分支
//如果是 application 啟動(dòng)模式,則加入 RuntimeInit
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
} else {
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
app_usage();
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
}
}
小結(jié)
app_main.cpp的代碼流程小結(jié)一下
- 初始化AndroidRuntime
- strcmp(arg, "--zygote") 設(shè)置為zygote啟動(dòng)模式
- args.add(String8("start-system-server"))給start函數(shù)的參數(shù)args賦值
- runtime.start("com.android.internal.os.ZygoteInit", args, zygote) 啟動(dòng)zygoteInit
從Android的系統(tǒng)架構(gòu)來(lái)看,硬件抽象層上面和JNI同級(jí)別的有一個(gè)Android runtime,ART的的初始化也是在zygote的啟動(dòng)流程中,接著就進(jìn)入了runtime的start()方法
//#AndroidRuntime.cpp
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
static const String8 startSystemServer("start-system-server");
// Whether this is the primary zygote, meaning the zygote which will fork system server.
bool primary_zygote = false;
/* start the virtual machine */
JniInvocation jni_invocation;
jni_invocation.Init(NULL); //初始化 JNI,加載 libart.so
JNIEnv* env;
//創(chuàng)建虛擬機(jī),其中大多數(shù)參數(shù)有系統(tǒng)屬性決定,最終startVm 利用 JNI_CreateJavaVM 創(chuàng)建虛擬機(jī)
if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
return;
}
//回調(diào) AppRuntime 的 onVmCreated 函數(shù)
//對(duì)于 zygote 進(jìn)程的啟動(dòng)流程而言,無(wú)實(shí)際操作,表示虛擬機(jī)創(chuàng)建完成,里面是空實(shí)現(xiàn)
onVmCreated(env);
//注冊(cè) JNI 函數(shù)
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
//替換string為實(shí)際路徑,將"com.android.internal.os.ZygoteInit" 替換為 “com/android/internal/os/ZygoteInit”
char* slashClassName = toSlashClassName(className != NULL ? className : "");
jclass startClass = env->FindClass(slashClassName); //找到class文件
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} else {
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V"); //通過(guò)反射找到ZygoteInit 的 main 函數(shù)
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
/* keep going */
} else {
env->CallStaticVoidMethod(startClass, startMeth, strArray); //調(diào)用ZygoteInit的main()函數(shù)
#if 0
if (env->ExceptionCheck())
threadExitUncaughtException(env);
#endif
}
}
free(slashClassName);
ALOGD("Shutting down VM\n");
if (mJavaVM->DetachCurrentThread() != JNI_OK) //退出當(dāng)前線程
ALOGW("Warning: unable to detach main thread\n");
if (mJavaVM->DestroyJavaVM() != 0) //創(chuàng)建一個(gè)線程,該線程會(huì)等待所有子線程結(jié)束后關(guān)閉虛擬機(jī)
ALOGW("Warning: VM did not shut down cleanly\n");
}
int AndroidRuntime::startReg(JNIEnv* env)
{
if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
env->PopLocalFrame(NULL);
return -1;
}
return 0;
}
static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env)
{
for (size_t i = 0; i < count; i++) {
if (array[i].mProc(env) < 0) {
return -1;
}
}
return 0;
}
static const RegJNIRec gRegJNI[] = {
REG_JNI(register_com_android_internal_os_RuntimeInit),
REG_JNI(register_com_android_internal_os_ZygoteInit_nativeZygoteInit),
REG_JNI(register_android_os_SystemClock),
......
}
struct RegJNIRec {
int (*mProc)(JNIEnv*);
};
從源代碼中找到主要的流程
- startVm 創(chuàng)建虛擬機(jī)
- startReg 注冊(cè)JNI方法
- env->CallStaticVoidMethod 使用JNI調(diào)用ZygoteInit 的main函數(shù),進(jìn)入java層
這部分就是zygote的c++代碼的主要業(yè)務(wù),會(huì)創(chuàng)建虛擬機(jī),也會(huì)注冊(cè)JNI方法,注冊(cè)JNI方法就是類似的一個(gè)方法名對(duì)應(yīng)的關(guān)聯(lián)代理,在AndroidRuntim.cpp文件中,就會(huì)查到相關(guān)的jni調(diào)用的函數(shù)指向,處理完這些,就會(huì)進(jìn)入java層的zygote流程
小結(jié)
從上面的流程可以看出,在Zygote進(jìn)程中通過(guò)startVm方法啟動(dòng)了虛擬機(jī),后續(xù)應(yīng)用進(jìn)程通過(guò)zygote孵化拷貝fork出新的進(jìn)程,就會(huì)復(fù)制zygote中的虛擬機(jī),所以每個(gè)應(yīng)用進(jìn)程會(huì)有自己獨(dú)立的虛擬機(jī),虛擬機(jī)的主要功能就是實(shí)現(xiàn)進(jìn)程的內(nèi)存管理(堆區(qū),方法區(qū),棧之類的),每個(gè)進(jìn)程獨(dú)立管理自己的內(nèi)存,遇到各種內(nèi)存問(wèn)題導(dǎo)致進(jìn)程崩潰而相互之間不會(huì)影響,做到了進(jìn)程間的隔離
Java層Zygote流程
上面的流程還是在c++代碼中,通過(guò)反射執(zhí)行到了ZygoteInit.main(),進(jìn)入了Java層的邏輯
//#ZygoteInit.java
public static void main(String argv[]) {
ZygoteServer zygoteServer = null; //
ZygoteHooks.startZygoteNoThreadCreation(); //調(diào)用native函數(shù),確保當(dāng)前沒(méi)有其他線程在運(yùn)行,主要出于安全的考慮
Runnable caller;
try {
boolean startSystemServer = false;
String zygoteSocketName = "zygote";
String abiList = null;
boolean enableLazyPreload = false;
//解析參數(shù),得到上述變量的值
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
} else if ("--enable-lazy-preload".equals(argv[i])) {
enableLazyPreload = true;
} else if (argv[i].startsWith(ABI_LIST_ARG)) {
abiList = argv[i].substring(ABI_LIST_ARG.length());
} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());
} else {
throw new RuntimeException("Unknown command line argument: " + argv[I]);
}
}
if (!enableLazyPreload) {
bootTimingsTraceLog.traceBegin("ZygotePreload");
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
preload(bootTimingsTraceLog); //默認(rèn)情況,預(yù)加載信息
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
bootTimingsTraceLog.traceEnd(); // ZygotePreload
}
zygoteServer = new ZygoteServer(isPrimaryZygote);
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer); //fork systemserver
// {@code r == null} in the parent (zygote) process, and {@code r != null} in the
// child (system_server) process.
if (r != null) {
r.run();
return;
}
}
// loops forever in the zygote.
caller = zygoteServer.runSelectLoop(abiList); //zygote 進(jìn)程進(jìn)入無(wú)限循環(huán),處理請(qǐng)求
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;
} finally {
if (zygoteServer != null) {
zygoteServer.closeServerSocket();
}
}
}
通過(guò)上述源碼,zygote的Java層啟動(dòng)流程梳理一下
- preload(bootTimingsTraceLog) 預(yù)加載資源,加快后續(xù)進(jìn)程的啟動(dòng),應(yīng)用進(jìn)程也是從zygote進(jìn)程孵化來(lái)的,一些系統(tǒng)的默認(rèn)資源在zygote進(jìn)行預(yù)加載,加快后續(xù)進(jìn)程孵化啟動(dòng)的速度
- zygoteServer = new ZygoteServer(isPrimaryZygote) 實(shí)例化socket
- Runnable r = forkSystemServer() 啟動(dòng)systemserver 進(jìn)程,AMS
- caller = zygoteServer.runSelectLoop(abiList) 死循環(huán),接收AMS傳過(guò)來(lái)的信息
到此Zygote進(jìn)程的啟動(dòng)流程結(jié)束,zygote進(jìn)程會(huì)去啟動(dòng)systemserver進(jìn)程,這個(gè)進(jìn)程跟各種系統(tǒng)服務(wù)有關(guān)系,zygote會(huì)通過(guò)socket的通信方式,接收其他進(jìn)程的請(qǐng)求,去孵化應(yīng)用進(jìn)程
總結(jié)
zygote進(jìn)程的啟動(dòng)分為native層和Java層
native層:
- 會(huì)去初始化運(yùn)行環(huán)境,創(chuàng)建jvm Android 虛擬機(jī)-AndroidRuntime ART
- 注冊(cè)JNI
- 調(diào)用zygoteInit.main進(jìn)入java層
java層:
- 預(yù)加載系統(tǒng)資源,加快后續(xù)應(yīng)用進(jìn)程的啟動(dòng)速度
- socket 跨進(jìn)程通信方案,接收其他進(jìn)程的消息
- 循環(huán)等待消息
zygote的流程走完了,下一篇開(kāi)始分析systemserver的流程了