一:背景
众所周知,Android应用及system_server基本都是由zygote fork出来的,那么zygote是如何启动的、又是如何接收fork进程的请求,接下来一步步揭秘。
二:启动流程
init进程是Android系统启动时,启动的第一个进程,其他所有进程基本都是由init进程来启动,其中也包括zygote,下面看下zygote的启动。
2.1 init进程启动zygote
init.rc里,在late-init阶段会触发zygote-start,zygote-start会启动zygote服务。在zygote服务中会启动app_process64(即zygote)并传入必要参数。
//system/core/rootdir/init.rc
on late-init
...
# Now we can start zygote.
trigger zygote-start
...
//system/core/rootdir/init.rc
on zygote-start
...
# 启动zygote服务
start zygote
start zygote_secondary
//system/core/rootdir/init.zygote64.rc
#启动app_process64时传参:-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
...
2.2 zygote初始化
2.2.1 AndroidRuntime.start
- 启动java虚拟机,根据"dalvik.vm.xxx"属性值进行初始化
- 注册jni函数
- 调用ZygoteInit的main函数
//frameworks/base/cmds/app_main.cpp
int main(int argc, char* const argv[])
{
...
bool zygote = false;
bool startSystemServer = false;
bool application = false;
String8 niceName;
String8 className;
++i; // Skip unused "parent dir" argument.
//获取启动参数并根据参数初始化zygote、startSystemServer等值
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 = (arg + 12);
} else if (strncmp(arg, "--", 2) != 0) {
className = arg;
break;
} else {
--i;
break;
}
}
...
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
...
}
//frameworks/base/core/jni/AndroidRuntime.cpp
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
...
bool primary_zygote = false;
for (size_t i = 0; i < options.size(); ++i) {
if (options[i] == startSystemServer) {
primary_zygote = true;
/* track our progress through the boot sequence */
const int LOG_BOOT_PROGRESS_START = 3000;
LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
addBootEvent("boot_progress_start");
}
}
...
//启动java虚拟机,根据"dalvik.vm.xxx"属性值进行初始化
if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
return;
}
...
//注册jni函数
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
...
//将className中的.替换为/ ,转换之后slashClassName的值为"com/android/internal/os/ZygoteInit"
char* slashClassName = toSlashClassName(className != NULL ? className : "");
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
...
} else {
//获取main函数
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
...
} else {
//调用ZygoteInit的main函数
env->CallStaticVoidMethod(startClass, startMeth, strArray);
}
}
...
}
2.2.2 ZygoteInit.main
- 在fork前做一些初始化工作,主要是enable DDMS
- 提前加载框架通用类和系统资源
- fork进程之前进行一次gc
- 初始化seLinux
- 初始化storage
- 创建zygote的服务端对象
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String[] argv) {
ZygoteServer zygoteServer = null;
...
//zygote运行在单独的进程组中
try {
Os.setpgid(0, 0);
}
...
Runnable caller;
try {
...
bootTimingsTraceLog.traceBegin("ZygoteInit");
//做fork前的一些初始化工作,主要是enable DDMS
RuntimeInit.preForkInit();
boolean startSystemServer = false;
String zygoteSocketName = "zygote";
String abiList = null;
boolean enableLazyPreload = false;
//根据传参做初始化
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]);
}
}
final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME);
...
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
}
bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
//fork进程之前进行一次gc
gcAndFinalize();
bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC
bootTimingsTraceLog.traceEnd(); // ZygoteInit
...
//native初始化
Zygote.initNativeState(isPrimaryZygote);
...
//创建zygote的服务端对象
zygoteServer = new ZygoteServer(isPrimaryZygote);
if (startSystemServer) {
//fork system_server进程
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
if (r != null) {
r.run();
return;
}
}
...
caller = zygoteServer.runSelectLoop(abiList);
}
...
//在单独的线程中接收来自应用的zygote请求
if (caller != null) {
caller.run();
}
}
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
static void preload(TimingsTraceLog bootTimingsTraceLog) {
...
//加载/system/etc/preloaded-classes定义的所有的类
preloadClasses();
...
//加载frameworks/base/core/res/res/values/arrays.xml中preloaded_drawables和preloaded_color_state_lists定义的所有资源
Resources.preloadResources();
...
//加载graphic的hal
nativePreloadAppProcessHALs();
...
//加载graphic
maybePreloadGraphicsDriver();
...
//加载android、jnigraphics、compiler_rt这三个共享库
preloadSharedLibraries();
//加载字体资源
preloadTextResources();
...
}
//frameworks/base/core/java/com/android/internal/os/Zygote.java
static void initNativeState(boolean isPrimary) {
nativeInitNativeState(isPrimary);
}
//frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
static void com_android_internal_os_Zygote_nativeInitNativeState(JNIEnv* env, jclass,
jboolean is_primary) {
//从环境中获取init创建的文件描述符。
gZygoteSocketFD =
android_get_control_socket(is_primary ? "zygote" : "zygote_secondary");
...
//创建用于向system_server发送未经请求的消息的socket,在app申请zygote fork进程时被调用,fork完成后关闭
initUnsolSocketToSystemServer();
...
//初始化seLinux
gIsSecurityEnforced = security_getenforce();
selinux_android_seapp_context_init();
//初始化storage
UnmountStorageOnInit(env);
//设置高优先级
if (!SetTaskProfiles(0, {})) {
zygote::ZygoteFailure(env, "zygote", nullptr, "Zygote SetTaskProfiles failed");
}
}
2.2.3 ZygoteInit.forkSystemServer
- 设置启动system_server的参数,例如uid、gid、进程名称等
- 调用Linux的fork函数来实现fork system_server进程
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
...
//设置启动system_server的参数
String[] args = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,"
+ "1024,1032,1065,3001,3002,3003,3005,3006,3007,3009,3010,3011,3012",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
"com.android.server.SystemServer",
};
...
try {
...
//fork system_server
pid = Zygote.forkSystemServer(...);
}
...
//子进程
if (pid == 0) {
...
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
...
}
//frameworks/base/core/java/com/android/internal/os/Zygote.java
static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
ZygoteHooks.preFork();
int pid = nativeForkSystemServer(
uid, gid, gids, runtimeFlags, rlimits,
permittedCapabilities, effectiveCapabilities);
//设置线程优先级为NORM_PRIORITY
Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
//ZygoteHooks.postForkCommon是Zygote进程中的一个钩子函数,它在Zygote进程fork出子进程后被调用。这个钩子函数的作用是在子进程中执行一些初始化操作,例如创建Binder线程池和消息循环等。
ZygoteHooks.postForkCommon();
return pid;
}
//frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
static jint com_android_internal_os_Zygote_nativeForkSystemServer(...) {
...
pid_t pid = zygote::ForkCommon(env, true,
fds_to_close,
fds_to_ignore,
true);
...
return pid;
}
//frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
pid_t zygote::ForkCommon(JNIEnv* env, bool is_system_server,
const std::vector<int>& fds_to_close,
const std::vector<int>& fds_to_ignore,
bool is_priority_fork,
bool purge) {
ATRACE_CALL();
if (is_priority_fork) {//设置最大优先级
setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MAX);
}
//设置信号处理程序
SetSignalHandlers();
...
//阻断信号
BlockSignal(SIGCHLD, fail_fn);
...
//真正fork进程的地方,在父进程中,fork()返回新创建子进程的PID,而在子进程中,fork()返回0。
pid_t pid = fork();
...
//解除阻断信号
UnblockSignal(SIGCHLD, fail_fn);
if (is_priority_fork && pid != 0) {//设置优先级为PROCESS_PRIORITY_DEFAULT
setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_DEFAULT);
}
return pid;
}
2.2.4 RuntimeInit.applicationInit
- 获取SystemServer.java类对应的ClassLoader
- 初始化时区、User-Agent等
- 开启线程池
- 调用SystemServer的main函数,开始启动系统服务等
这个时候system_server进程就启动了,开始启动系统服务等
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
...
if (parsedArgs.mInvokeWith != null) {
...
} else {
//获取SystemServer.java类对应的ClassLoader
ClassLoader cl = getOrCreateSystemServerClassLoader();
...
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mDisabledCompatChanges,
parsedArgs.mRemainingArgs, cl);
}
}
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
...
//初始化时区、User-Agent等
RuntimeInit.commonInit();
//开启线程池
ZygoteInit.nativeZygoteInit();
return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
classLoader);
}
//frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
...
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
//frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
try {
//获取SystemServer类
cl = Class.forName(className, true, classLoader);
}
...
Method m;
try {
//获取main函数
m = cl.getMethod("main", new Class[] { String[].class });
}
...
//调用SystemServer的main函数,开始启动系统服务等
return new MethodAndArgsCaller(m, argv);
}
2.2.5 ZygoteServer.runSelectLoop
在线程里启动一个死循环,接收请求fork的socket请求
//frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
Runnable runSelectLoop(String abiList) {
...
while (true) {
...
if (pollReturnValue == 0) {
...
} else {
...
while (--pollIndex >= 0) {
if (pollIndex == 0) {
...
} else if (pollIndex < usapPoolEventFDIndex) {
try {
//获取socket连接
ZygoteConnection connection = peers.get(pollIndex);
boolean multipleForksOK = !isUsapPoolEnabled()
&& ZygoteHooks.isIndefiniteThreadSuspensionSafe();
//处理来自应用请求fork的socket请求
final Runnable command =
connection.processCommand(this, multipleForksOK);
}
...
}
}
...
}
...
}
}
三:小结
3.1 zygote进程是否只有一个?
答:不是。
zygote进程一般都会有zygote和zygote64两个,分别用来fork32位和64位的应用,这两个进程都是在init.rc中启动的。
如果系统中有webview类应用,那么还会存在webview_zygote这个进程,用来fork webview类应用。webview_zygote进程的启动是在ProcessList的startProcess函数中判断是否是webview类型应用,如果是则会调用Process的startWebView函数,接着会判断webview_zygote进程是否存在,如果不存在则调用zygote fork出来。
3.2 是否每次应用冷启动时都要调用zygote的fork函数?
答:不是。
Android系统有usap机制,会在Android系统启动时,开启一个进程池。如果usap功能打开,当有fork请求到来时,会先从进程池中取出一个进程返回,节约启动时间。