当前位置: 首页 > news >正文

system_server或Zygote进程死亡后,Zygote fork出的app子进程销毁流程

下面按Android 15 / AOSP 主线实现输出结论、关键代码路径和校验方法。重点回答:system_server 或 Zygote 死亡后,由 Zygote fork 出来的 app 进程如何被销毁

首先给出数据证据,确认system_server和app的process group来自zygote:

adb shell ps -ef |grep -Ei "test|system_server|zygote" root 431 1 0 10:13:32 ? 00:00:01 zygote64 system 785 431 6 10:13:34 ? 00:00:16 system_server webview_zygote 1144 431 0 10:13:36 ? 00:00:00 webview_zygote u10_a211 3023 431 0 10:14:21 ? 00:00:00 com.example.test adb shell cat /proc/785/stat 785 (system_server) S 431 431 0 0 -1 4194624 189396 1902 1086 0 1075 558 0 1 18 -2 237 0 724 18295746560 92123 18446744073709551615 96517870370816 96517870375168 140733830651120 0 0 0 4612 1 1073775864 0 0 0 17 3 0 0 0 0 0 96517870403584 96517870403608 96517893808128 140733830654952 140733830655051 140733830655051 140733830660062 0 adb shell cat /proc/1144/stat 1144 (webview_zygote) S 431 431 0 0 -1 4194624 2618 0 20 0 1 0 0 0 20 0 5 0 916 34071162880 23922 18446744073709551615 96517870370816 96517870375168 140733830651120 0 0 0 4612 1 1073775864 0 0 0 17 3 0 0 0 0 0 96517870403584 96517870403608 96517893808128 140733830654952 140733830655051 140733830655051 140733830660062 0 adb shell cat /proc/3023/stat 3023 (om.example.test) S 431 431 0 0 -1 4194624 18081 0 7 0 76 14 0 0 10 -10 23 0 5476 17149894656 42262 18446744073709551615 96517870370816 96517870375168 140733830651120 0 0 0 4612 1 1073775864 0 0 0 17 2 0 0 0 0 0 96517870403584 96517870403608 96517893808128 140733830654952 140733830655051 140733830655051 140733830660062 0

1. 结论概览

1.1 system_server 死亡后的销毁链路

system_server 是 Zygote fork 出来的关键子进程;Zygote 会监听子进程 SIGCHLD,一旦发现死亡的是 system_server,就会主动 kill 自己。经典逻辑是 Zygote 的 SigChldHandler 中 waitpid(-1, ..., WNOHANG) 回收子进程,若 pid == gSystemServerPid,则执行 kill(getpid(), SIGKILL) 让 Zygote 自杀。 [blog.csdn.net], [codeleading.com]

随后init 作为 Zygote 的父进程收到 SIGCHLD,进入 service reap 流程;Zygote service 不是 oneshot,因此 init 会对该 service 的进程组执行 SIGKILL 清理,并按 rc 配置重启 Zygote。init 对子进程 SIGCHLD 的监听、ReapAnyOutstandingChildren()、Service::Reap()、KillProcessGroup(SIGKILL) 这一套机制,在 Android init 中用于回收死亡服务并重启非 oneshot 服务。 [juejin.cn], [cnblogs.com]

因此:system_server 死亡 → Zygote 自杀 → init 回收 Zygote service → init kill Zygote 进程组/相关子进程 → Zygote 重启 → system_server 重新 fork → Java framework 重建。Zygote 和 system_server 在设计上是“共存亡”的关系;system_server 死亡会触发 Zygote 退出,而 Zygote 退出会由 init 处理并重启。 [blog.csdn.net], [jianshu.com]

1.2 Zygote 死亡后的 app 进程销毁链路

Zygote 自身死亡时,app 进程不是靠 AMS 正常逐个 kill 的,因为 system_server/AMS 也会随 Zygote 重启链路一起失效;真正兜底的是 init 对 Zygote service 的 reap/kill process group 逻辑。在 Service::Reap() 中,非 oneshot service 退出时会调用 KillProcessGroup(SIGKILL),其目的就是杀掉该服务进程组中残留的子进程,防止旧 Zygote fork 出来的进程继续运行。 [juejin.cn], [cnblogs.com]

Android Zygote 启动时会把自己放入独立进程组,ZygoteInit.main() 中存在 Os.setpgid(0, 0) 这类逻辑,Zygote fork 出来的 system_server/app 进程天然和 Zygote 有同源进程关系;旧版本文档和源码分析中也明确指出 Zygote 挂掉时 init 会 kill 其进程组,从而清理 system_server 和 app 子进程。 [juejin.cn], [blog.csdn.net]

简单说:app 进程的销毁不是由新 Zygote 或新 system_server 事后“扫描旧 app 再 kill”,而是 Zygote service 死亡瞬间,由 init 的 service reap / process group kill 机制完成大清场。

2. 关键流程图

1场景 A:system_server 死亡

2

3system_server crash / kill

4

5Zygote 收到 SIGCHLD

6

7Zygote SigChldHandler waitpid()

8

9发现 pid == gSystemServerPid

10

11Zygote kill(getpid(), SIGKILL) 自杀

12

13init 收到 Zygote SIGCHLD

14

15Service::Reap(zygote)

16

17KillProcessGroup(SIGKILL)

18

19清理旧 Zygote 进程组及其 fork 出来的 app / system_server 残留进程

20

21执行 onrestart

22

23重启 Zygote

24

25新 Zygote fork 新 system_server

1场景 B:Zygote 自身死亡

2

3zygote crash / kill

4

5init 收到 SIGCHLD

6

7Service::Reap(zygote)

8

9KillProcessGroup(SIGKILL)

10

11清理旧 Zygote 进程组中的残留子进程

12

13执行 init.zygote*.rc 中 onrestart 命令

14

15重启 zygote / zygote_secondary

16

17新 system_server 启动

18

19系统服务重新建立,app 进程重新按需启动

3. 涉及类 / 文件

模块

关键文件 / 类

作用

init

system/core/init/init.cpp

安装 SIGCHLD 监听,init 主循环处理子进程退出。 [juejin.cn], [blog.csdn.net]

init

system/core/init/sigchld_handler.cpp

ReapAnyOutstandingChildren() 回收退出子进程。 [juejin.cn], [blog.csdn.net]

init

system/core/init/service.cpp

Service::Reap() 中 kill service 进程组并重启非 oneshot 服务。 [cnblogs.com], [juejin.cn]

init rc

system/core/rootdir/init.zygote64.rc / init.zygote64_32.rc

定义 Zygote service、socket、onrestart、critical 等。 [blog.csdn.net], [juejin.cn]

Zygote

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

Zygote Java 入口,preload、fork system_server、runSelectLoop。 [juejin.cn], [blog.csdn.net]

Zygote

frameworks/base/core/java/com/android/internal/os/Zygote.java

调用 native fork system_server/app。 [juejin.cn], [cnblogs.com]

Zygote native

frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

fork、SIGCHLD handler、system_server 死亡时 kill Zygote。 [blog.csdn.net], [codeleading.com]

system_server

frameworks/base/services/java/com/android/server/SystemServer.java

system_server Java 入口,启动 AMS/PMS/WMS 等系统服务。 [juejin.cn], [blog.csdn.net]

4. 关键代码校验点

说明:下面代码片段是为了说明机制,实际 Android 15 代码请以本地 AOSP android-15.0.0_r* tag 为准。AOSP 官方说明源码由 Google 托管在 Git 仓库中,可通过 repo init / repo sync 获取;也可用 cs.android.com 在线浏览。 [source.and....google.cn], [mirrors.tu...hua.edu.cn]

4.1 init.zygote*.rc:Zygote 由 init 管理,不是 oneshot

Android 15 典型 init.zygote64.rc / init.zygote64_32.rc 中,Zygote service 形态如下:

1service zygote /system/bin/app_process64 -Xzygote /system/bin \

2--zygote --start-system-server --socket-name=zygote

3class main

4priority -20

5user root

6group root readproc reserved_disk

7socket zygote stream 660 root system

8socket usap_pool_primary stream 660 root system

9onrestart restart audioserver

10onrestart restart cameraserver

11onrestart restart media

12onrestart restart netd

13onrestart restart wificond

14task_profiles ProcessCapacityHigh MaxPerformance

15critical window=${zygote.critical_window.minute:-off} target=zygote-fatal

校验点:

  • 没有oneshot:Zygote 死亡后 init 会按常驻 service 处理,进入 restart 流程。 [juejin.cn], [blog.csdn.net]
  • onrestart:Zygote 重启时会联动重启 audioserver、cameraserver、media、netd、wificond 等服务。 [blog.csdn.net], [juejin.cn]
  • critical:Android 15 配置中 Zygote 是 critical service,短时间频繁崩溃会触发更高等级故障处理。 [blog.csdn.net], [blog.csdn.net]

4.2 ZygoteInit:启动时 fork system_server,随后进入 select loop

1// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

2

3if(startSystemServer) {

4Runnabler=forkSystemServer(abiList, zygoteSocketName, zygoteServer);

5

6// r == null: parent zygote

7// r != null: child system_server

8if(r!=null) {

9r.run();

10return;

11}

12}

13

14Log.i(TAG,"Accepting command socket connections");

15caller=zygoteServer.runSelectLoop(abiList);

校验点:

  • Zygote 启动后会先 fork system_server,然后父进程继续 runSelectLoop() 等待 AMS/ProcessList 请求 fork app。 [juejin.cn], [blog.csdn.net]
  • app 进程并不是 system_server 直接 fork() 出来的,而是 system_server 通过 socket 请求 Zygote fork。AOSP 文档也说明 Zygote 作为 root/孵化器,负责生成系统和应用进程,system_server 通过 Unix domain socket 请求 Zygote 创建进程。 [source.and....google.cn], [blog.csdn.net]

4.3 Zygote native:system_server 死亡时 Zygote 自杀

关键逻辑如下:

1// frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

2

3staticvoidSigChldHandler(int/*signal_number*/) {

4pid_tpid;

5intstatus;

6

7while((pid=waitpid(-1,&status, WNOHANG))>0) {

8if(pid==gSystemServerPid) {

9ALOGE("Exit zygote because system server (%d) has terminated", pid);

10kill(getpid(), SIGKILL);

11}

12}

13}

校验点:

  • Zygote 监听所有子进程 SIGCHLD。 [blog.csdn.net], [jianshu.com]
  • 只有死亡的是 gSystemServerPid 时,Zygote 才会主动 SIGKILL 自己。 [blog.csdn.net], [codeleading.com]
  • 普通 app 进程死亡不会导致 Zygote 自杀;普通 app 死亡由 AMS/ProcessList 维护进程状态,必要时重启对应组件。此点可从 handler 只判断 gSystemServerPid 推出。 [blog.csdn.net], [jianshu.com]

4.4 init:Zygote service 死亡后 kill process group

init 对 service 退出的通用处理如下:

1// system/core/init/service.cpp

2

3voidService::Reap(constsiginfo_t&siginfo) {

4if(!(flags_&SVC_ONESHOT)||(flags_&SVC_RESTART)) {

5KillProcessGroup(SIGKILL);

6}

7

8pid_=0;

9flags_&=(~SVC_RUNNING);

10

11// 非 disabled / reset service 后续进入 restart

12flags_|=SVC_RESTARTING;

13onrestart_.ExecuteAllCommands();

14}

校验点:

  • init 通过 SIGCHLD 知道子服务退出,然后 ReapOneProcess() 找到对应 Service 并调用 Service::Reap()。 [juejin.cn], [blog.csdn.net]
  • 对非 oneshot service,Service::Reap() 会调用 KillProcessGroup(SIGKILL),用于杀掉该服务进程组中的残留进程。 [cnblogs.com], [juejin.cn]
  • Zygote service 没有 oneshot,所以 Zygote 死亡会走 kill process group + restart 逻辑。 [blog.csdn.net], [juejin.cn]

5. app 进程到底在哪里被 kill?

5.1 不是 AMS 正常 kill

当 system_server 已经挂了,AMS 自身也不存在了;因此不可能依赖 AMS 按 ProcessRecord 一个个执行正常 kill。system_server 是承载 AMS/PMS/WMS 等 Java framework 服务的核心进程,死亡后 framework 控制面已经失效。 [blog.csdn.net], [segmentfault.com]

5.2 不是 Zygote 自己遍历 kill app

Zygote 的 SIGCHLD handler 主要做的是回收子进程并判断 gSystemServerPid;发现 system_server 死亡后,Zygote 选择 kill(getpid(), SIGKILL) 自杀,而不是遍历所有 app pid。 [blog.csdn.net], [jianshu.com]

5.3 真正兜底:init kill Zygote service 进程组

Zygote 被 kill 后,init 作为其父进程收到 SIGCHLD,进入 Service::Reap();Zygote 非 oneshot,因此 init 会 KillProcessGroup(SIGKILL) 清理旧 Zygote service 相关进程,达到销毁旧 app 进程的目的。 [cnblogs.com], [juejin.cn]

6. 本地代码校验命令

建议在 Android 15 源码根目录执行:

1# 1. 确认源码 tag

2repomanifest-r|grep-E"android-15|platform/frameworks/base|platform/system/core"

3

4# 2. 校验 zygote rc

5grep-R"service zygote"-nsystem/core/rootdir/init.zygote*.rc

6grep-R"critical window=.*zygote-fatal"-nsystem/core/rootdir/init.zygote*.rc

7grep-R"onrestart restart"-nsystem/core/rootdir/init.zygote*.rc

8

9# 3. 校验 ZygoteInit fork system_server

10grep-R"forkSystemServer"-nframeworks/base/core/java/com/android/internal/os/ZygoteInit.java

11grep-R"runSelectLoop"-nframeworks/base/core/java/com/android/internal/os/ZygoteInit.java

12

13# 4. 校验 native SIGCHLD / system_server death

14grep-R"gSystemServerPid"-nframeworks/base/core/jni/com_android_internal_os_Zygote.cpp

15grep-R"Exit zygote because system server"-nframeworks/base/core/jni/com_android_internal_os_Zygote.cpp

16grep-R"SIGCHLD"-nframeworks/base/core/jni/com_android_internal_os_Zygote.cpp

17

18# 5. 校验 init 子进程回收

19grep-R"InstallSignalFdHandler"-nsystem/core/init

20grep-R"ReapAnyOutstandingChildren"-nsystem/core/init

21grep-R"Service::Reap"-nsystem/core/init

22grep-R"KillProcessGroup"-nsystem/core/init

如果第 4 步能查到 gSystemServerPid、waitpid、kill(getpid(), SIGKILL) 相关代码,第 5 步能查到 Service::Reap() 中对非 oneshot service 调用 KillProcessGroup(SIGKILL),就可以确认本文结论成立。

7. 最终结论

Android 15 上,system_server 死亡后,Zygote 会通过 SIGCHLD 发现gSystemServerPid退出,然后主动 SIGKILL 自己;Zygote 死亡后,init 会回收 Zygote service,并对该 service 的进程组执行 SIGKILL 清理,旧 Zygote fork 出来的 app 进程随之被销毁。之后 init 根据init.zygote*.rc重启 Zygote,新 Zygote 再 fork 新 system_server,系统服务重新建立。

一句话总结:

1system_server 死亡

2→ Zygote 自杀

3→ init reap zygote

4→ init KillProcessGroup(SIGKILL)

5→ 旧 app 进程被清理

6→ Zygote / system_server 重启

1Zygote 直接死亡

2→ init reap zygote

3→ init KillProcessGroup(SIGKILL)

4→ 旧 app 进程被清理

5→ Zygote / system_server 重启

http://www.jsqmd.com/news/1116480/

相关文章:

  • 告别论文多工具内耗:okbiye 一体化毕业论文创作工作台,一站式搞定全学段学位文稿
  • Obsidian高效笔记的终极神器:Templater插件完全指南
  • 6DoF运动追踪技术解析与IIM-42652 IMU应用实践
  • 从零部署到实战:深度解析CyberStrikeAI自动化安全测试平台
  • Si5351A时钟发生器与PIC18F25K80的硬件协同设计
  • VMPDump终极指南:如何快速破解VMProtect保护的Windows程序
  • 13DOF传感器与PIC18F26K80实现高性价比定位导航方案
  • 开源商城系统如何选?不同企业场景对应不同商城源码,一篇看懂市面上众多开源商城项目
  • 用过才敢说!盘点2026年当红之选的AI论文网站
  • 6DoF运动跟踪技术:从IMU到姿态解算的工程实践
  • 3分钟掌握WPS-Zotero插件:告别繁琐文献管理,提升学术写作效率80%
  • 华为云WAF实战:精准防御SQL注入与XSS攻击
  • 高效电机驱动系统设计与TC78H660FTG应用
  • Python爬虫经典案例第45篇:电子书网站爬取——Project Gutenberg电子书采集实战
  • 网上书店系统(SSM+Vue3前后端分离)完整源码分享 | Java毕业设计含数据库脚本+开发文档
  • Figma中文插件:3步实现Figma界面全中文化,设计师效率提升50%
  • 自建房装电梯井道动工前,先做好这几件事
  • 把混乱未来变成一个方向的庖丁解牛
  • 高效直流有刷电机驱动方案设计与优化
  • devkit-pipeline自动化测试框架:DevKitTester的10个高级技巧
  • 5分钟搞定浏览器Markdown阅读:免费扩展的终极使用指南
  • 基于FOC的无刷电机控制方案设计与实现
  • 重新定义Windows界面美学:DWMBlurGlass技术原理与实战应用
  • ICM-42688-P与PIC18LF26J50在机器人控制与工业监测中的应用
  • 基于STM32单片机宠物自动喂食系统喂水控制系统 WIFI监控宠物喂养1(设计源文件+万字报告+讲解)(支持资料、图片参考_降重降ai)
  • 4-20mA电流环与INA196在工业检测中的抗干扰设计
  • STM32G031K8与KMX62 IMU在运动控制中的实践应用
  • Python爬虫经典案例第51篇:代码片段平台爬取——GitHub Gist数据采集实战
  • IMU传感器与6DoF姿态解算在嵌入式系统中的应用
  • 【全网首发】v2.1.198 史诗级大更新:Claude for Chrome 正式商用、Agent 自动提 PR 闭环、API 瞬时断流终极自愈!