rokevin
移动
前端
语言
  • 基础

    • Linux
    • 实施
    • 版本构建
  • 应用

    • WEB服务器
    • 数据库
  • 资讯

    • 工具
    • 部署
开放平台
产品设计
  • 人工智能
  • 云计算
计算机
其它
GitHub
移动
前端
语言
  • 基础

    • Linux
    • 实施
    • 版本构建
  • 应用

    • WEB服务器
    • 数据库
  • 资讯

    • 工具
    • 部署
开放平台
产品设计
  • 人工智能
  • 云计算
计算机
其它
GitHub
  • Zygote

Zygote

init -> zygote进程 -> SystemServer进程 -> 各种系统服务进程 -> 应用进程

/**
 * Special method to start the system server process. In addition to the
 * common actions performed in forkAndSpecialize, the pid of the child
 * process is recorded such that the death of the child process will cause
 * zygote to exit.
 *
 * @param uid the UNIX uid that the new process should setuid() to after
 * fork()ing and and before spawning any threads.
 * @param gid the UNIX gid that the new process should setgid() to after
 * fork()ing and and before spawning any threads.
 * @param gids null-ok; a list of UNIX gids that the new process should
 * setgroups() to after fork and before spawning any threads.
 * @param runtimeFlags bit flags that enable ART features.
 * @param rlimits null-ok an array of rlimit tuples, with the second
 * dimension having a length of 3 and representing
 * (resource, rlim_cur, rlim_max). These are set via the posix
 * setrlimit(2) call.
 * @param permittedCapabilities argument for setcap()
 * @param effectiveCapabilities argument for setcap()
 *
 * @return 0 if this is the child, pid of the child
 * if this is the parent, or -1 on error.
 */
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;
}

private static native int nativeForkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
        int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);

Zygote(中文常译 “受精卵”)是 Android 系统中所有 Java 进程的 “孵化器”,其核心作用是通过预加载资源和共享进程内存,大幅减少后续 App 及系统进程(如 SystemServer)的启动时间,是 Android 高效启动机制的关键组件。

Zygote 的核心定位与设计初衷

在 Android 诞生前,传统 Linux 系统中每个新进程启动时都需重新加载虚拟机、框架类库等基础资源,导致进程启动慢且内存占用高。

Zygote 的设计初衷就是解决这一问题,核心思路是:

  1. 提前加载:在系统启动初期,Zygote 进程一次性加载 Java 虚拟机(ART/Dalvik)、系统核心类库(如 android.os.*、java.lang.*)和系统资源(如 framework-res.apk)。
  2. 进程共享:通过 Linux 的 fork() 机制孵化新进程,新进程会继承 Zygote 已加载的资源(共享内存页,写时复制),无需重复加载,实现 “一键孵化”。

最终效果:App 进程启动时间从秒级缩短到毫秒级,同时减少内存冗余占用。

Zygote 的启动流程(从系统开机到就绪)

Zygote 是系统启动早期由 init 进程启动的关键进程,启动流程可分为 4 个阶段:

阶段 1:由 init 进程触发启动(系统初始化阶段)

Android 系统开机后,Linux 内核首先启动 init 进程(系统第一个用户态进程),init 进程通过解析 /init.rc(初始化配置文件)触发 Zygote 启动:

  1. 解析配置:init.rc 中定义了 Zygote 的启动脚本,指定了启动程序路径和参数:

    # /init.rc 中 Zygote 启动配置(以 64 位系统为例)
    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
        onrestart write /sys/android_power/request_state wake
        onrestart write /sys/power/state on
        onrestart restart audioserver
        onrestart restart cameraserver
    
  2. 启动 Zygote 进程:init 进程执行 /system/bin/app_process64 程序(Zygote 的可执行文件),并传入启动参数(如 --zygote 表示以 Zygote 模式运行,--start-system-server 表示启动后需孵化 SystemServer)。

阶段 2:Zygote 初始化(加载虚拟机与核心资源)

app_process64 启动后,执行 ZygoteInit.main() 方法,完成 Zygote 自身初始化:

  1. 启动 Java 虚拟机(ART/Dalvik):
    • 调用 AndroidRuntime.startVm() 初始化虚拟机,设置虚拟机参数(如堆内存大小、垃圾回收策略)。
    • 注册 JNI 方法(如 java.lang.String 的 native 方法),建立 Java 层与 Native 层的通信桥梁。
  2. 预加载系统核心类:
    • 读取 /system/etc/preloaded-classes 文件(包含需预加载的类列表,如 android.app.Activity、java.util.ArrayList)。
    • 通过 ClassLoader 批量加载这些类到虚拟机,后续孵化的进程可直接复用,无需重复加载。
  3. 预加载系统资源:
    • 调用 Resources.preloadResources() 加载系统资源(如 /system/framework/framework-res.apk 中的 drawable、layout、string 等)。
    • 预加载主题资源(如默认 App 主题),避免后续 App 启动时加载资源耗时。
  4. 初始化 Binder 通信通道:
    • 创建 ZygoteSocket(UNIX 域套接字),用于接收其他进程(如 SystemServer、AMS)的进程孵化请求。
    • 将 ZygoteSocket 注册到系统,监听端口(通过 runSelectLoop() 进入循环监听状态)。

阶段 3:孵化 SystemServer 进程(系统核心服务容器)

Zygote 初始化完成后,首先孵化 SystemServer 进程(系统所有核心服务的运行容器),这是 Zygote 启动后的第一个任务:

  1. 构造 SystemServer 启动参数:
    • 配置高权限参数:--setuid=1000(SystemServer 的 UID 为系统用户,拥有最高权限)、--setgid=1000、--nice-name=system_server(进程名)。
    • 指定主类路径:com.android.server.SystemServer(SystemServer 的入口类)。
  2. 执行 fork () 系统调用:
    • 调用 Zygote.forkSystemServer() 方法,通过 Linux 的 fork() 机制创建子进程(SystemServer)。
    • 父进程(Zygote):fork 成功后返回子进程 PID,继续监听 ZygoteSocket,准备孵化后续 App 进程。
    • 子进程(SystemServer):fork 成功后返回 0,执行 handleSystemServerProcess() 方法,进入 SystemServer 自身初始化流程(如启动 AMS、WMS 等服务)。

阶段 4:进入循环监听(等待孵化 App 进程)

孵化 SystemServer 后,Zygote 调用 runSelectLoop() 进入 永久循环监听状态,等待 AMS 发送的 App 进程孵化请求:

  1. 监听 ZygoteSocket:通过 IO 多路复用(select() 系统调用)监听 ZygoteSocket 上的请求,避免阻塞。

  2. 处理孵化请求

    :当 AMS 需要启动新 App 时(如用户点击图标),会通过 Binder 发送请求到 Zygote:

    • Zygote 接收请求(包含 App 的 UID、GID、包名、主类路径等参数)。
    • 调用 Zygote.forkAndSpecialize() 孵化新 App 进程(与 fork SystemServer 类似,但权限更低)。
    • 新 App 进程初始化后,执行 ActivityThread.main() 方法,启动 App 主线程。
  3. 持续服务:Zygote 会一直运行到系统关机,为所有 App 进程提供孵化服务。

Zygote 的核心特性(为什么能高效孵化进程)

  1. 写时复制(Copy-On-Write,COW):
    • Zygote 孵化新进程时,通过 Linux 的 COW 机制共享内存页:新进程初始时不复制 Zygote 的内存,仅当新进程修改内存数据(如修改某个类的静态变量)时,才复制对应的内存页。
    • 大幅减少内存占用(如多个 App 共享 Zygote 预加载的类和资源,无需各存一份)。
  2. 预加载机制:
    • 提前加载系统类和资源,避免后续进程重复加载,缩短启动时间(App 进程启动时无需加载 android.app.Activity 等基础类)。
  3. 单一父进程:
    • 所有 Java 进程(包括 SystemServer 和 App)都由 Zygote 孵化,形成 “Zygote → 子进程” 的树形结构,便于系统统一管理(如进程优先级调整、内存回收)。
  4. 权限隔离:
    • 孵化不同进程时配置不同的 UID/GID(如 App 进程的 UID 从 10000 开始,SystemServer 的 UID 为 1000),实现进程间权限隔离,保障系统安全。

Zygote 与其他核心组件的关系

组件与 Zygote 的交互方式
init 进程Zygote 的父进程,通过 /init.rc 启动 Zygote,Zygote 崩溃时 init 会重启 Zygote。
SystemServerZygote 的第一个子进程,由 Zygote 孵化后启动系统核心服务;SystemServer 中的 AMS 会向 Zygote 发送 App 孵化请求。
AMS通过 ZygoteSocket 向 Zygote 发送 App 进程孵化请求(如 startActivity() 时启动目标 App 进程);Zygote 孵化完成后,AMS 管理 App 进程的生命周期。
App 进程所有 App 进程都是 Zygote 的子进程,继承 Zygote 预加载的类和资源;App 进程崩溃时,由 AMS 通知 Zygote 重新孵化(可选)。

总结

Zygote 是 Android 系统的 “进程孵化器”,通过 预加载资源、写时复制、统一孵化 三大核心机制,实现了进程的高效启动和内存的优化利用。其启动流程贯穿系统初始化阶段,从 init 进程触发到孵化 SystemServer,再到持续监听 App 孵化请求,是连接底层 Linux 内核与上层 Java 组件的关键桥梁。理解 Zygote 的工作原理,是掌握 Android 进程管理和启动优化的核心基础。

最近更新:: 2025/10/28 00:33
Contributors: luokaiwen