Zygote(受精卵进程)是 Android 系统中所有 Java 应用程序进程及 SystemServer 的父进程。扮演"孵化器"角色,负责孵化系统中所有应用程序进程,通过 fork 机制和写时复制(Copy-on-Write)技术,加速进程创建并减少内存占用。
一、整体流程概览
Zygote 的启动经历了从 Linux 内核空间 到 Native C++ 空间,最后进入 Java 空间 的过程。
- init 进程:解析 .rc 脚本,启动 app_process 二进制文件。
- Native 阶段:初始化 AndroidRuntime,启动 ART 虚拟机并注册 JNI。
- Java 阶段:ZygoteInit 预加载资源,启动 SystemServer。
- 循环阶段:进入 ZygoteServer 循环,等待 Socket 消息孵化应用。
二、第一阶段:Native 层启动 (app_process)
1. 入口:app_main.cpp
源码路径 :frameworks/base/cmds/app_process/app_main.cpp
init进程根据 init.zygote64.rc 中的配置启动。main 函数是起点:
- 识别身份:通过判断参数中是否有 --zygote 来确定自己作为 Zygote 启动。
- 准备参数:指定主类名为 com.android.internal.os.ZygoteInit。
- 调用 Runtime:
c++
// 启动 AndroidRuntime
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
2. 核心桥梁:AndroidRuntime.cpp
源码路径 :frameworks/base/core/jni/AndroidRuntime.cpp
runtime.start 函数完成了 Native 到 Java 的惊险一跃:
- startVm() :启动 ART (Android Runtime)。配置堆大小、JIT 编译模式、GC 策略等。
- startReg():注册系统核心 JNI 方法。这使得 Java 代码可以调用 Native 的驱动接口和底层
- JNI 调用
c++
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
......
char* slashClassName = toSlashClassName(className != NULL ? className : "");
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} else {
// 找到 Java 层的 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);
/* keep going */
} else {
// 正式进入 Java 世界
env->CallStaticVoidMethod(startClass, startMeth, strArray);
}
}
}
......
三、 第二阶段:Java 层初始化 (ZygoteInit)
源码路径 :frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
进入 ZygoteInit.main() 后,Zygote 开始构建"受精卵"的基因:
1. 预加载资源 (Preload)
这是 Android 启动优化的核心,通过 preload() 方法:
- preloadClasses():从 /system/etc/preloaded-classes 加载数千个核心 Java 类。
- preloadResources():加载系统 Framework 的资源文件(图标、布局)。
- preloadSharedLibraries():加载常用的动态链接库。
- 优势 :子进程在 fork 时直接共享这些内存,只有在修改时才会物理复制(COW 机制)
2. 创建 ZygoteServer (Socket)
Zygote 会创建一个名为 zygote 的 LocalServerSocket ,用于接收来自 ActivityManagerService (AMS) 的进程启动请求。
四、 第三阶段:孵化 SystemServer
Zygote 初始化完成后,第一个任务就是启动 SystemServer,它是 Android 大脑的载体。
-
Fork 进程:调用 Zygote.forkSystemServer()。
-
身份分化:
- 父进程 (Zygote):继续执行 runSelectLoop 监听 Socket。
- 子进程 (SystemServer):
- 调用 handleSystemServerProcess。
- 关闭继承自 Zygote 的不需要的 Socket 和资源。
- 最终通过反射调用 com.android.server.SystemServer.main()。
五、 第四阶段:运行循环 (ZygoteServer、ZygoteInit)
Zygote 最后会通过 runSelectLoop() 进入阻塞等待状态: 源码路径 :frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
java
Runnable runSelectLoop(String abiList) {
while (true) {
// 使用 poll/select 监听 Socket 消息
StructPollfd[] pollFds = ...;
Os.poll(pollFds, -1);
while(-pollIndex >= 0){
if (pollIndex == 0) {
// 当收到 AMS 发来的命令时
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
socketFDs.add(newPeer.getFileDescriptor());
} else if (pollIndex < usapPoolEventFDIndex) {
ZygoteConnection connection = peers.get(pollIndex);
boolean multipleForksOK = !isUsapPoolEnabled()
&& ZygoteHooks.isIndefiniteThreadSuspensionSafe();
// 执行 fork 逻辑
final Runnable command = connection.processCommand(this, multipleForksOK);
if (mIsForkChild) {
if (command == null) {
throw new IllegalStateException("command == null");
}
return command;
} else {
if (command != null) {
throw new IllegalStateException("command != null");
}
if (connection.isClosedByPeer()) {
connection.closeSocket();
peers.remove(pollIndex);
socketFDs.remove(pollIndex);
}
}
}
}
}
}
run子进程执行应用入口 源码路径 :frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
java
public static void main(String[] argv) {
......
if (caller != null) {
caller.run();
}
}
六、 总结
Zygote 的启动是 "由厚变薄" 的过程:
- 由厚:它在启动时加载了大量的类和资源,导致自身占用了较大的内存。
- 变薄:由于 Linux 的 fork 机制,后续启动的所有 App 进程都共享 Zygote 的这一份内存空间(Copy-on-Write机制,COW)。
在 AOSP 15 中,这种设计依然是系统响应速度和内存效率的基础。同时 AOSP 15 进一步优化了 ZygoteCommandBuffer 机制,减少了 fork 过程中的跨层调用开销。