Zygote进程的启动
Android系统中有三个关键进程:init进程、SystemServer进程和Zygote进程。Zygote是系统运行的第一个Dalvik虚拟机进程,且负责孵化开启其它的APP应用进程。
Zygote进程是由Linux内核启动的用户级init进程启动,现在就来了解一下Zygote进程的启动流程。至于Linux进程0、内核进程是如何启动的这里不深入讨论,参考计算机专业的书籍《Linux内核设计的艺术》。
init进程启动其它服务包括Zygote都是通过init.rc文件来启动,该文件是用Android初始化语言编写。位于:/system/core/rootdir。可以看见其中首先inport了Zygote的配置文件:
...
import /init.usb.configfs.rc
import /init.${ro.zygote}.rc一共有下面这四种脚本文件:
init.zygote32.rc :纯32位模式
init.zygote64_32.rc:混64位模式(64位为主,32位为辅)
init.zygote64.rc:纯64位模式
init.zygote32_64.rc:混32位模式(32位为主,64位为辅)
脚本都是Android初始化语言用来启动app_process进程,也就是以后的Zygote进程。以init.zygote64_32.rc为例:
service zygote /system/bin/app_process32 -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
socket usap_pool_primary stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
onrestart restart wificond
writepid /dev/cpuset/foreground/tasks
service zygote_secondary /system/bin/app_process64 -Xzygote /system/bin --zygote --socket-name=zygote_secondary
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
writepid /dev/cpuset/foreground/tasks通过Android初始化语言启动了两个Service服务:zygote和zygote_secondary。再
执行frameworks/base/cmds/app_process/app_main.cpp目录下的app_main.cpp文件。在其中的main方法中:
while (i < argc) {
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) {
zygote = true;
niceName = ZYGOTE_NICE_NAME;
} else if (strcmp(arg, "--start-system-server") == 0) {
startSystemServer = true;
} else if (strcmp(arg, "--application") == 0) {
application = true;
} else if (strncmp(arg, "--nice-name=", 12) == 0) {
niceName.setTo(arg + 12);
} else if (strncmp(arg, "--", 2) != 0) {
className.setTo(arg);
break;
} else {
--i;
break;
}
}
...
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {
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.");
}在Linux内核中Zygote进程通过fork自己来启动其它APP进程,并且通过zygote判断否是自己当前Zygote进程,
AndroidRuntime类定义于frameworks/base/core/jni目录下AndroidRuntime.cpp文件中,其中AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)方法:
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
...
/*
* 启动JVM虚拟机
*/
JNIEnv* env;
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
onVmCreated(env);
/*
* 为JVM虚拟机注册JNI方法
*/
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
...
/*
* 启动VM。 该线程成为VM的主线程,并且在VM退出之前不会返回.
*/
char* slashClassName = toSlashClassName(className != NULL ? className : "");
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* 继续 */
} else {
//找到ZygoteInit的main方法
jmethodID startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
/* 继续 */
} else {
//通过JNI调用ZygoteInit的main方法
env->CallStaticVoidMethod(startClass, startMeth, strArray);
#if 0
if (env->ExceptionCheck())
threadExitUncaughtException(env);
#endif
}
}
...
}前面都是C++代码,在Native层。接下来到了Java框架层。
从ZygoteInit的main方法开始:
@UnsupportedAppUsage
public static void main(String argv[]) {
ZygoteServer zygoteServer = null;
...
Runnable caller;
try {
...
// 在某些配置中,我们避免急于预加载资源和类。
//在这种情况下,我们会在第一个fork之前预先加载东西。
if (!enableLazyPreload) {
bootTimingsTraceLog.traceBegin("ZygotePreload");
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
preload(bootTimingsTraceLog);
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
bootTimingsTraceLog.traceEnd(); // ZygotePreload
} else {
Zygote.resetNicePriority();
}
...
Zygote.initNativeState(isPrimaryZygote);
ZygoteHooks.stopZygoteNoThreadCreation();
zygoteServer = new ZygoteServer(isPrimaryZygote);
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
if (r != null) {
r.run();
return;
}
}
// select循环在派生之后在子进程的早期返回,并在Zygote中永久循环。
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
throw ex;
} finally {
if (zygoteServer != null) {
zygoteServer.closeServerSocket();
}
}
// 我们在子进程中,已经退出选择循环。 继续执行命令。
if (caller != null) {
caller.run();
}
}其中会调用forkSystemServer(String abiList, String socketName,ZygoteServer zygoteServer)方法返回Runnable对象。以前源码该方法名为startSystemServer。
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
long capabilities = posixCapabilitiesAsBits(
OsConstants.CAP_IPC_LOCK,
OsConstants.CAP_KILL,
OsConstants.CAP_NET_ADMIN,
OsConstants.CAP_NET_BIND_SERVICE,
OsConstants.CAP_NET_BROADCAST,
OsConstants.CAP_NET_RAW,
OsConstants.CAP_SYS_MODULE,
OsConstants.CAP_SYS_NICE,
OsConstants.CAP_SYS_PTRACE,
OsConstants.CAP_SYS_TIME,
OsConstants.CAP_SYS_TTY_CONFIG,
OsConstants.CAP_WAKE_ALARM,
OsConstants.CAP_BLOCK_SUSPEND
);
...
try {
parsedArgs = new ZygoteArguments(args);
Zygote.applyDebuggerSystemProperty(parsedArgs);
Zygote.applyInvokeWithSystemProperty(parsedArgs);
boolean profileSystemServer = SystemProperties.getBoolean(
"dalvik.vm.profilesystemserver", false);
if (profileSystemServer) {
parsedArgs.mRuntimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
}
/* 请求fork系统服务进程*/
pid = Zygote.forkSystemServer(
parsedArgs.mUid, parsedArgs.mGid,
parsedArgs.mGids,
parsedArgs.mRuntimeFlags,
null,
parsedArgs.mPermittedCapabilities,
parsedArgs.mEffectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* 对于fork的子进程,也就是应用进程 */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
return null;
}调用Zygote.forkSystemServer方法中fork服务进程:
public static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
ZygoteHooks.preFork();
// Resets nice priority for zygote process.
resetNicePriority();
int pid = nativeForkSystemServer(
uid, gid, gids, runtimeFlags, rlimits,
permittedCapabilities, effectiveCapabilities);
// Enable tracing as soon as we enter the system_server.
if (pid == 0) {
Trace.setTracingEnabled(true, runtimeFlags);
}
ZygoteHooks.postForkCommon();
return pid;
}接着又会到Native层调用底层的nativeForkSystemServer方法fork出一个Server进程。
private static native int nativeForkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);回到ZygoteInit的main方法,继续运行ZygoteServer的runSelectLoop方法,进入无限循环,处理来自AMS的Socket请求,如何处理AMS创建APP进程请求见APP进程启动流程一文。运行Zygote进程的select循环:
/**
* 运行Zygote进程的select循环。
* 接受新的连接,并从连接中读取命令,一次生成一个请求。
*/
Runnable runSelectLoop(String abiList) {
ArrayList<FileDescriptor> socketFDs = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
//无限循环
while (true) {
fetchUsapPoolPolicyPropsWithMinInterval();
int[] usapPipeFDs = null;
StructPollfd[] pollFDs = null;
// 考虑到轮询结构,请分配足够的空间
//此Zygote的USAP池的状态(可以是常规Zygote,WebView Zygote或AppZygote)。
if (mUsapPoolEnabled) {
usapPipeFDs = Zygote.getUsapPipeFDs();
pollFDs = new StructPollfd[socketFDs.size() + 1 + usapPipeFDs.length];
} else {
pollFDs = new StructPollfd[socketFDs.size()];
}
...
}
}
}相关博客:

