Android随笔-Zygote是什么?

Zygote 是 Android 系统中的"进程孵化器 ",是所有 Android 应用进程的父进程 。它的核心设计思想是"预加载 + fork",通过一次加载、多次复用,实现应用进程的极速启动。

一、Zygote 是什么

属性 说明
本质 一个特殊的 Android 进程,由 init 进程启动
位置 源码路径:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
启动方式 init 进程通过 init.zygote64.rc 配置启动 /system/bin/app_process64
核心机制 预加载系统资源 → 进入循环等待 → 收到请求后 fork 子进程
子进程 SystemServer(系统服务进程)+ 所有 Android 应用进程

二、Zygote 的三大核心作用

1. 预加载系统资源(Preload)

Zygote 启动时会预先加载大量系统类和资源,避免每个应用重复加载:

java 复制代码
// ZygoteInit.java --- preload() 核心方法
private static void preload() {
    preloadClasses();        // 加载 /system/etc/preloaded-classes 中的类
    preloadResources();      // 加载 framework-res.apk 资源
    preloadSharedLibraries(); // 加载 libandroid.so 等共享库
    preloadOpenGL();       // 加载 OpenGL 纹理
    gcAndFinalize();       // fork 前强制 GC,减少子进程内存
}

预加载的类示例(preloaded-classes 文件):

android.app.ActivityThread

android.content.ContextImpl

android.view.View

android.widget.TextView

...

内存节省原理 :fork() 采用 Copy-on-Write(写时拷贝),子进程共享父进程的只读内存页 。预加载的类在只读状态下被所有应用共享,100 个应用共享同一份 framework 类,极大节省内存。

2. 创建 SystemServer

Zygote 启动后首先 fork 出 SystemServer 进程,承载 AMS、WMS、PMS 等核心系统服务:

java 复制代码
// ZygoteInit.java --- forkSystemServer()
if (startSystemServer) {
    Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
    if (r != null) {
        r.run();  // 在子进程(SystemServer)中执行
        return;   // 父进程(Zygote)继续往下走
    }
}

fork 的两次返回

  • 父进程(Zygote):返回子进程的 PID
  • 子进程(SystemServer):返回 0,执行 r.run() 启动 SystemServer.main()

3. 孵化应用进程

Zygote 通过 Socket 接收 AMS 的请求,fork 出所有 Android 应用进程:

java 复制代码
// ZygoteInit.java --- 进入无限循环等待
caller = zygoteServer.runSelectLoop(abiList);
java 复制代码
// ZygoteServer.java --- 核心监听循环
Runnable runSelectLoop(String abiList) {
    ArrayList<FileDescriptor> socketFDs = new ArrayList<>();
    socketFDs.add(mZygoteSocket.getFileDescriptor());
    
    while (true) {
        // poll() 阻塞等待 AMS 连接
        int pollReturnValue = Os.poll(pollFDs, -1);
        
        if (pollIndex == 0) {
            // AMS 发来请求,接受连接
            ZygoteConnection newPeer = acceptCommandPeer(abiList);
            // ... 处理 fork 请求
        }
    }
}

三、Zygote 启动全流程

Step 1: init 进程启动 Zygote(init.zygote64.rc)

ruby 复制代码
# /system/core/rootdir/init.zygote64.rc
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
    class main
    priority -20
    user root
    group root readproc reserved_disk
    socket zygote stream 660 root system      # 创建 /dev/socket/zygote
    socket usap_pool_primary stream 660 root system
    onrestart restart audioserver
    onrestart restart cameraserver
    ...

关键:init 进程创建 zygote 命名 Socket,Zygote 后续通过该 Socket 与 AMS 通信。

Step 2: C++ 层入口(app_main.cpp)

c 复制代码
// /frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[]) {
    AppRuntime runtime(argv[0], ...);
    
    bool zygote = false;
    bool startSystemServer = false;
    
    // 解析参数 --zygote 和 --start-system-server
    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;
        }
    }
    
    // 启动 Zygote
    if (zygote) {
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    }
}

Step 3: 创建 JVM(AndroidRuntime.cpp)

cpp 复制代码
// /frameworks/base/core/jni/AndroidRuntime.cpp
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote) {
    // 创建 Dalvik/ART 虚拟机
    if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
        return;
    }
    
    // 注册 JNI 方法
    if (startReg(env) < 0) {
        return;
    }
    
    // 通过 JNI 调用 ZygoteInit.main()
    jclass startClass = env->FindClass("com/android/internal/os/ZygoteInit");
    jmethodID startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V");
    env->CallStaticVoidMethod(startClass, startMeth, strArray);
}

Step 4: Java 层主类(ZygoteInit.java)

java 复制代码
// /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String[] argv) {
    ZygoteServer zygoteServer = null;
    
    // 标记 Zygote 开始,禁止创建线程(fork 安全)
    ZygoteHooks.startZygoteNoThreadCreation();
    
    try {
        // 1. 预加载系统资源
        preload(bootTimingsTraceLog);
        
        // 2. 强制 GC,减少 fork 后子进程内存
        gcAndFinalize();
        
        // 3. 创建 Socket 服务
        zygoteServer = new ZygoteServer(isPrimaryZygote);
        
        // 4. fork SystemServer
        if (startSystemServer) {
            Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
            if (r != null) {
                r.run();  // 子进程执行 SystemServer
                return;
            }
        }
        
        // 5. 进入无限循环,等待 AMS 请求
        Log.i(TAG, "Accepting command socket connections");
        caller = zygoteServer.runSelectLoop(abiList);
        
    } finally {
        zygoteServer.closeServerSocket();
    }
}

Step 5: Socket 创建与监听(ZygoteServer.java)

java 复制代码
// /frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
ZygoteServer(boolean isPrimaryZygote) {
    mUsapPoolEventFD = Zygote.getUsapPoolEventFD();
    
    // 创建 /dev/socket/zygote
    if (isPrimaryZygote) {
        mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.PRIMARY_SOCKET_NAME);
    }
}

// 从 init 环境变量获取 Socket 文件描述符
static LocalServerSocket createManagedSocketFromInitSocket(String socketName) {
    String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;  // "ANDROID_SOCKET_zygote"
    String env = System.getenv(fullSocketName);
    int fileDesc = Integer.parseInt(env);
    
    FileDescriptor fd = new FileDescriptor();
    fd.setInt$(fileDesc);
    return new LocalServerSocket(fd);  // 开始监听
}

Step 6: fork 应用进程(Zygote.java)

java 复制代码
// /frameworks/base/core/java/com/android/internal/os/Zygote.java
static int forkAndSpecialize(int uid, int gid, int[] gids, ...) {
    // native 方法,调用 Linux fork()
    return nativeForkAndSpecialize(uid, gid, gids, ...);
}

fork 后子进程会执行:

java 复制代码
// 子进程关闭继承的 Socket,避免影响父进程
zygoteServer.closeServerSocket();

// 执行应用入口 ActivityThread.main()
caller.run();

四、总结

Zygote = 预加载器 + 进程孵化器

特性 作用
预加载 一次加载 framework 类/资源,所有应用共享,节省内存
fork 快速复制进程,避免重复初始化 JVM 和加载类
Socket 单线程阻塞监听,与 AMS 通信安全、简单
SystemServer Zygote 的第一个子进程,承载整个 Android 系统服务

一句话 :Zygote 是 Android 系统的"种子进程",没有它,就没有任何应用能在 Android 上运行。

相关推荐
小虎牙0071 小时前
Android kotlin图片库Coil源码详解
android·前端
AFinalStone2 小时前
Android 7系统网络(一)全景图与调用链路概览
android·网络·frameworks
用户86022504674722 小时前
Android DEX 内存 Dump 全流程实战:从 APK 提取到无特征内存盲扫
android
杉氧5 小时前
兼容与共生:如何在旧项目中优雅地引入 Compose?
android·架构·android jetpack
Flynt6 小时前
Room 3.0 包名重构 + KMP 迁移:我把项目升级踩了个遍
android·数据库·kotlin
杉氧6 小时前
性能优化实战:如何定位冗余重组并榨干 Compose 的每一帧性能?
android·架构·android jetpack
阿pin8 小时前
Android随笔-ATMS与AMS区别与联系
android·ams·atms
alexhilton18 小时前
将应用迁移到Navigation 3:痛点、加班和紧急修复
android·kotlin·android jetpack
杉氧1 天前
Navigation Compose 深度实践:如何优雅地串联起你的全栈 App?
android·架构·android jetpack