Zygote 是 Android 操作系统中的一个进程,它充当具有相同应用程序二进制接口 (ABI) 的所有系统进程和应用进程的根。
在 Pixel 7 及更高版本等现代设备上,有一个 64 位 Zygote 进程。此外,主要 ABI 还有一个 WebView Zygote,它是一个专门的 Zygote,其中包含特定于运行 WebView 的进程的库和资源。
以下是 Zygote 执行的任务
当 Android 操作系统初始化时,init 守护程序会生成 Zygote 进程。在某些双架构系统上,会生成两个 Zygote 进程(一个 64 位和一个 32 位)。本页仅介绍单架构系统。
Zygote 可以立即派生称为未特化应用进程 (USAP) 的进程,或者等待应用程序需要时再派生进程。必须通过系统属性或 Android 调试桥命令启用前一种选项。有关配置 Zygote 以立即派生进程的更多信息,请参阅启用未特化应用进程池。
如果您的设备上启用了 USAP 池
- 系统服务器使用 Unix 域套接字连接到池中可用的 USAP。系统服务器请求 USAP 通过更改进程的 ID (PID)、cgroup 和其他信息来预配置以供应用程序使用。
- 当 USAP 完成预配置后,它会向系统服务器回复 PID。
- 当应用程序占用其中一个 USAP 时,该 USAP 不再是池的一部分。当池中 USAP 达到一个或更少时,Zygote 会用新的 USAP 补充池。
如果您的 Zygote 使用惰性求值派生进程
- 系统服务器收到应用程序需要进程的命令。
- 系统服务器使用 Unix 域套接字向相应的 Zygote 发送命令。
- Zygote fork 进程并更改 PID、cgroup 和其他信息。
- 当进程完成时,它会将 PID 发送回 Zygote,然后 Zygote 将其传递回系统服务器。
启用 USAP 池
要启用 USAP 池的使用,请执行以下操作之一
将
dalvik.vm.usap_pool_enabled
系统属性设置为true
,位于/build/make/target/product/runtime_libart.mk
中。运行以下命令
adb shell am broadcast -a \"com.google.android.gms.phenotype.FLAG_OVERRIDE\" --es package \"com.google.android.platform.runtime_native\" --es user \"\*\" --esa flags \"usap_pool_enabled\" --esa values \"true\" --esa types \"string\" com.google.android.gms
启用此功能后,每个 Zygote 都会维护一个 fork 进程池,这些进程执行应用程序启动过程中与应用程序无关的部分。
问题排查 Zygote 问题
本节包含 Zygote 相关问题的解决方案。
Zygote 崩溃
如果您的设备无法正常重启,并且您的日志或崩溃报告显示 Zygote 存在问题,则很可能是因为您最近所做的更改导致 initd 或系统服务器崩溃。修复您的代码应该可以解决问题。
SELinux 拒绝或 IO 失败
Zygote 对跨进程边界的文件描述符卫生要求很高。当 fork 时存在文件描述符,但不在允许列表中时,我们使用 dup
系统调用 /dev/null
以防止缓存的文件描述符被意外地用于访问新打开的文件。
如果您正在进行框架更改,包括尝试将资源加载到 Zygote 中,并且您收到 SELinux 拒绝或 IO 失败
对于未命名的文件描述符,当调用
Restat
时,请将文件描述符包含在fds_to_ignore
向量中。对于命名的文件描述符
- 编辑
WORKING_DIRECTORY/frameworks/base/core/jni/fd_utils.cpp
。 - 将路径添加到打开文件的允许列表。
- 编辑