Android启动的第一个虚拟机称为Zygote,这也是Android中重要的一个虚拟机。在system\core\rootdir\init.rc脚本中,Zygote的启动配置如下:
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
Zygote进程的启动过程位于frameworks\base\cmds\app_process\app_main.cpp文件中,app_main.cpp中描述了应用进程(app_process)的启动模式:zygote模式和非zygote模式。应用进程的命令行参数为:
app_process [java-options] cmd-dir start-class-name [options]
由此可以明白,在启动Zygote进程时,app_process的java-options选项为-Xzygote;cmd-dir选项为/system/bin,即当前目录;start-class-name为zygote,即进程名。
Zygote虚拟机的具体启动过程如下:
代码1-1 app_process实现
int main(int argc, const char* const argv[])
{
//全局变量在ProcessState.cpp中定义
mArgC=argc;
mArgV=argv;
mArgLen=0;
for (int i=0; i<argc; i++) {
mArgLen+=strlen(argv[i]) + 1;
}
mArgLen--;
AppRuntime runtime;
const char *arg;
const char *argv0;
argv0=argv[0];
argc--;
argv++;
//添加VM参数
int i=runtime.addVmArguments(argc, argv);
if (i<argc) {
runtime.mParentDir=argv[i++]; //设置父路径
}
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); //启动zygote进程
}
else { //非zygote进程的启动
set_process_name(argv0);
runtime.mClassName=arg;
runtime.mArgC=argc-i;
runtime.mArgV=argv+i;
LOGV("App process is starting with pid=%d, class=%s.\n",
getpid(), runtime.getClassName());
runtime.start();
}
}
else {
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
app_usage();
return 10;
}
}
当进程的启动模式为zygote模式时,系统会调用com.android.internal.os.ZygoteInit启动系统服务器;当进程启动模式为非zygote模式时,系统会调用com.android.internal.os.RuntimeInit启动进程。关于com.android.internal.os.ZygoteInit的实现位于frameworks\base\core\java\com\android\internal\os\ZygoteInit.java文件中,更详细的内容将在2.3.4节实时进程中讨论。
无论进程以何种模式启动,终将会执行Android Runtime::start(const char* className, const bool startSystem Server)函数,然后经过一系列的参数配置终启动一个Dalvik虚拟机。相关的代码分布在app_main.cpp、Jni.c、init.c等文件中,启动Dalvik虚拟机的过程如图1-1所示。

图1-1 启动Dalvik虚拟机
在创建Dalvik虚拟机之前,系统会首先阻塞管道信号,接着检查Dalvik虚拟机的相关属性,如dalvik.vm.checkjni、dalvik.vm.execution-mode、dalvik.vm.stack-trace-file、dalvik. vm.enableassertions、dalvik.vm.jniopts、dalvik.vm.dexopt-flags、dalvik.vm.deadlock-predict等,然后调用JNI_CreateJavaVM()函数创建Dalvik虚拟机,后为Dalvik虚拟机进行原生方法的注册。