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 上运行。

相关推荐
千里马学框架4 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台4 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone4 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc4 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo4 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077004 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼4 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone5 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen5 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone5 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui