第一板块:Android 系统基石与运行原理 | 第四篇:进程孵化(Zygote)与 Low Memory Killer 机制

第一板块:Android 系统基石与运行原理 | 第四篇:进程孵化(Zygote)与 Low Memory Killer 机制

所属板块:第一板块 --- Android 系统基石与运行原理

前置知识:第三篇中的 ART 虚拟机原理、Linux 进程(fork/exec)、Linux 内存管理基础

本篇定位 :解析 Android 系统最核心的进程孵化机制内存回收机制 。深入剖析 Zygote 如何通过 fork() 快速创建应用进程,以及 Low Memory Killer (LMK) 如何在系统内存不足时依据**进程优先级(oom_adj)**选择性杀掉进程。全程无性能优化建议、无保活黑科技、仅保留 Linux 内核与 Android Framework 的标准化定义。


1. 核心结论先行

Android 应用进程并非由系统随意创建,而是由一个名为 Zygote 的"受精卵"进程 fork(分裂) 而来。

  • Zygote 的核心价值预热与共享。它在系统启动时预加载了 ART 虚拟机、Framework 核心类库和资源。当应用启动时,只需复制(Copy-on-Write)Zygote 的内存空间,极大降低了启动耗时和内存占用。
  • Low Memory Killer 的核心逻辑按优先级杀进程 。Android 为每个进程分配一个 oom_adj 分数(越低越重要)。当内存不足时,内核会优先杀掉分数最高的进程。

2. Zygote 进程孵化机制

2.1 系统启动与 Zygote 初始化流程

#mermaid-svg-sXao1UVV4Bb7Puc7{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-sXao1UVV4Bb7Puc7 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-sXao1UVV4Bb7Puc7 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-sXao1UVV4Bb7Puc7 .error-icon{fill:#552222;}#mermaid-svg-sXao1UVV4Bb7Puc7 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-sXao1UVV4Bb7Puc7 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-sXao1UVV4Bb7Puc7 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-sXao1UVV4Bb7Puc7 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-sXao1UVV4Bb7Puc7 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-sXao1UVV4Bb7Puc7 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-sXao1UVV4Bb7Puc7 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-sXao1UVV4Bb7Puc7 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-sXao1UVV4Bb7Puc7 .marker.cross{stroke:#333333;}#mermaid-svg-sXao1UVV4Bb7Puc7 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-sXao1UVV4Bb7Puc7 p{margin:0;}#mermaid-svg-sXao1UVV4Bb7Puc7 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-sXao1UVV4Bb7Puc7 .cluster-label text{fill:#333;}#mermaid-svg-sXao1UVV4Bb7Puc7 .cluster-label span{color:#333;}#mermaid-svg-sXao1UVV4Bb7Puc7 .cluster-label span p{background-color:transparent;}#mermaid-svg-sXao1UVV4Bb7Puc7 .label text,#mermaid-svg-sXao1UVV4Bb7Puc7 span{fill:#333;color:#333;}#mermaid-svg-sXao1UVV4Bb7Puc7 .node rect,#mermaid-svg-sXao1UVV4Bb7Puc7 .node circle,#mermaid-svg-sXao1UVV4Bb7Puc7 .node ellipse,#mermaid-svg-sXao1UVV4Bb7Puc7 .node polygon,#mermaid-svg-sXao1UVV4Bb7Puc7 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-sXao1UVV4Bb7Puc7 .rough-node .label text,#mermaid-svg-sXao1UVV4Bb7Puc7 .node .label text,#mermaid-svg-sXao1UVV4Bb7Puc7 .image-shape .label,#mermaid-svg-sXao1UVV4Bb7Puc7 .icon-shape .label{text-anchor:middle;}#mermaid-svg-sXao1UVV4Bb7Puc7 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-sXao1UVV4Bb7Puc7 .rough-node .label,#mermaid-svg-sXao1UVV4Bb7Puc7 .node .label,#mermaid-svg-sXao1UVV4Bb7Puc7 .image-shape .label,#mermaid-svg-sXao1UVV4Bb7Puc7 .icon-shape .label{text-align:center;}#mermaid-svg-sXao1UVV4Bb7Puc7 .node.clickable{cursor:pointer;}#mermaid-svg-sXao1UVV4Bb7Puc7 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-sXao1UVV4Bb7Puc7 .arrowheadPath{fill:#333333;}#mermaid-svg-sXao1UVV4Bb7Puc7 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-sXao1UVV4Bb7Puc7 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-sXao1UVV4Bb7Puc7 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-sXao1UVV4Bb7Puc7 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-sXao1UVV4Bb7Puc7 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-sXao1UVV4Bb7Puc7 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-sXao1UVV4Bb7Puc7 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-sXao1UVV4Bb7Puc7 .cluster text{fill:#333;}#mermaid-svg-sXao1UVV4Bb7Puc7 .cluster span{color:#333;}#mermaid-svg-sXao1UVV4Bb7Puc7 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-sXao1UVV4Bb7Puc7 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-sXao1UVV4Bb7Puc7 rect.text{fill:none;stroke-width:0;}#mermaid-svg-sXao1UVV4Bb7Puc7 .icon-shape,#mermaid-svg-sXao1UVV4Bb7Puc7 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-sXao1UVV4Bb7Puc7 .icon-shape p,#mermaid-svg-sXao1UVV4Bb7Puc7 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-sXao1UVV4Bb7Puc7 .icon-shape .label rect,#mermaid-svg-sXao1UVV4Bb7Puc7 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-sXao1UVV4Bb7Puc7 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-sXao1UVV4Bb7Puc7 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-sXao1UVV4Bb7Puc7 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Zygote 进程 (父进程)
创建虚拟机 (ART)
注册 Android 核心类
预加载系统资源

(Theme/Style/Drawable)
创建 Socket 服务端

(/dev/socket/zygote)
无限循环等待连接
Linux Init 进程 (PID 1)
启动
init.rc 脚本
Zygote 进程

(pid=2000)

深度解析:Zygote 的"预热"清单

Zygote 在 fork() 之前所做的工作,决定了后续应用启动的速度:

预加载项 具体内容 学术意义
ART 虚拟机 启动 Heap、JIT、GC 线程 避免每个应用重复初始化运行时环境
Class Preloading preloaded-classes 文件(约 4000+ 个类) 包含 ActivityViewString 等核心类,通过 Class.forName() 加载到内存
Resource Preloading framework-res.apk 中的 Drawable、ColorStateList 避免每个应用重复解析 XML 资源
Shared Libraries libandroid_runtime.so 通过 dlopen() 加载,供所有应用共享

2.2 应用进程孵化(Fork)流程

当 AMS(ActivityManagerService)请求启动应用时,Zygote 执行 fork() 操作。
新应用进程 Zygote 进程 ActivityManagerService 新应用进程 Zygote 进程 ActivityManagerService #mermaid-svg-V6KLhAd3hW7LSL4P{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-V6KLhAd3hW7LSL4P .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-V6KLhAd3hW7LSL4P .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-V6KLhAd3hW7LSL4P .error-icon{fill:#552222;}#mermaid-svg-V6KLhAd3hW7LSL4P .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-V6KLhAd3hW7LSL4P .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-V6KLhAd3hW7LSL4P .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-V6KLhAd3hW7LSL4P .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-V6KLhAd3hW7LSL4P .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-V6KLhAd3hW7LSL4P .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-V6KLhAd3hW7LSL4P .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-V6KLhAd3hW7LSL4P .marker{fill:#333333;stroke:#333333;}#mermaid-svg-V6KLhAd3hW7LSL4P .marker.cross{stroke:#333333;}#mermaid-svg-V6KLhAd3hW7LSL4P svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-V6KLhAd3hW7LSL4P p{margin:0;}#mermaid-svg-V6KLhAd3hW7LSL4P .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-V6KLhAd3hW7LSL4P text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-V6KLhAd3hW7LSL4P .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-V6KLhAd3hW7LSL4P .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-V6KLhAd3hW7LSL4P .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-V6KLhAd3hW7LSL4P .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-V6KLhAd3hW7LSL4P #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-V6KLhAd3hW7LSL4P .sequenceNumber{fill:white;}#mermaid-svg-V6KLhAd3hW7LSL4P #sequencenumber{fill:#333;}#mermaid-svg-V6KLhAd3hW7LSL4P #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-V6KLhAd3hW7LSL4P .messageText{fill:#333;stroke:none;}#mermaid-svg-V6KLhAd3hW7LSL4P .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-V6KLhAd3hW7LSL4P .labelText,#mermaid-svg-V6KLhAd3hW7LSL4P .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-V6KLhAd3hW7LSL4P .loopText,#mermaid-svg-V6KLhAd3hW7LSL4P .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-V6KLhAd3hW7LSL4P .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-V6KLhAd3hW7LSL4P .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-V6KLhAd3hW7LSL4P .noteText,#mermaid-svg-V6KLhAd3hW7LSL4P .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-V6KLhAd3hW7LSL4P .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-V6KLhAd3hW7LSL4P .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-V6KLhAd3hW7LSL4P .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-V6KLhAd3hW7LSL4P .actorPopupMenu{position:absolute;}#mermaid-svg-V6KLhAd3hW7LSL4P .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-V6KLhAd3hW7LSL4P .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-V6KLhAd3hW7LSL4P .actor-man circle,#mermaid-svg-V6KLhAd3hW7LSL4P line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-V6KLhAd3hW7LSL4P :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 此时父子进程共享同一份内存页 (COW) 子进程开始写入数据触发 Copy-On-Write 1. 通过 Socket 发送请求 (fork)2. fork() 系统调用3. 返回子进程 PID4. 绑定 Application 类5. 执行 onCreate()


2.3 Fork 与 Copy-On-Write (COW) 原理

这是 Zygote 高效的核心。以下是进程内存布局的变化流程图:
#mermaid-svg-SIMevBwnpxS8yqNi{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-SIMevBwnpxS8yqNi .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-SIMevBwnpxS8yqNi .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-SIMevBwnpxS8yqNi .error-icon{fill:#552222;}#mermaid-svg-SIMevBwnpxS8yqNi .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-SIMevBwnpxS8yqNi .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-SIMevBwnpxS8yqNi .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-SIMevBwnpxS8yqNi .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-SIMevBwnpxS8yqNi .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-SIMevBwnpxS8yqNi .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-SIMevBwnpxS8yqNi .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-SIMevBwnpxS8yqNi .marker{fill:#333333;stroke:#333333;}#mermaid-svg-SIMevBwnpxS8yqNi .marker.cross{stroke:#333333;}#mermaid-svg-SIMevBwnpxS8yqNi svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-SIMevBwnpxS8yqNi p{margin:0;}#mermaid-svg-SIMevBwnpxS8yqNi .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-SIMevBwnpxS8yqNi .cluster-label text{fill:#333;}#mermaid-svg-SIMevBwnpxS8yqNi .cluster-label span{color:#333;}#mermaid-svg-SIMevBwnpxS8yqNi .cluster-label span p{background-color:transparent;}#mermaid-svg-SIMevBwnpxS8yqNi .label text,#mermaid-svg-SIMevBwnpxS8yqNi span{fill:#333;color:#333;}#mermaid-svg-SIMevBwnpxS8yqNi .node rect,#mermaid-svg-SIMevBwnpxS8yqNi .node circle,#mermaid-svg-SIMevBwnpxS8yqNi .node ellipse,#mermaid-svg-SIMevBwnpxS8yqNi .node polygon,#mermaid-svg-SIMevBwnpxS8yqNi .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-SIMevBwnpxS8yqNi .rough-node .label text,#mermaid-svg-SIMevBwnpxS8yqNi .node .label text,#mermaid-svg-SIMevBwnpxS8yqNi .image-shape .label,#mermaid-svg-SIMevBwnpxS8yqNi .icon-shape .label{text-anchor:middle;}#mermaid-svg-SIMevBwnpxS8yqNi .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-SIMevBwnpxS8yqNi .rough-node .label,#mermaid-svg-SIMevBwnpxS8yqNi .node .label,#mermaid-svg-SIMevBwnpxS8yqNi .image-shape .label,#mermaid-svg-SIMevBwnpxS8yqNi .icon-shape .label{text-align:center;}#mermaid-svg-SIMevBwnpxS8yqNi .node.clickable{cursor:pointer;}#mermaid-svg-SIMevBwnpxS8yqNi .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-SIMevBwnpxS8yqNi .arrowheadPath{fill:#333333;}#mermaid-svg-SIMevBwnpxS8yqNi .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-SIMevBwnpxS8yqNi .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-SIMevBwnpxS8yqNi .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-SIMevBwnpxS8yqNi .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-SIMevBwnpxS8yqNi .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-SIMevBwnpxS8yqNi .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-SIMevBwnpxS8yqNi .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-SIMevBwnpxS8yqNi .cluster text{fill:#333;}#mermaid-svg-SIMevBwnpxS8yqNi .cluster span{color:#333;}#mermaid-svg-SIMevBwnpxS8yqNi div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-SIMevBwnpxS8yqNi .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-SIMevBwnpxS8yqNi rect.text{fill:none;stroke-width:0;}#mermaid-svg-SIMevBwnpxS8yqNi .icon-shape,#mermaid-svg-SIMevBwnpxS8yqNi .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-SIMevBwnpxS8yqNi .icon-shape p,#mermaid-svg-SIMevBwnpxS8yqNi .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-SIMevBwnpxS8yqNi .icon-shape .label rect,#mermaid-svg-SIMevBwnpxS8yqNi .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-SIMevBwnpxS8yqNi .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-SIMevBwnpxS8yqNi .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-SIMevBwnpxS8yqNi :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-SIMevBwnpxS8yqNi .event>*{fill:#f9f9f9!important;stroke:#333!important;stroke-width:2px!important;stroke-dasharray:5 5!important;}#mermaid-svg-SIMevBwnpxS8yqNi .event span{fill:#f9f9f9!important;stroke:#333!important;stroke-width:2px!important;stroke-dasharray:5 5!important;}#mermaid-svg-SIMevBwnpxS8yqNi .highlight>*{fill:#ffcdd2!important;stroke:#c62828!important;stroke-width:2px!important;}#mermaid-svg-SIMevBwnpxS8yqNi .highlight span{fill:#ffcdd2!important;stroke:#c62828!important;stroke-width:2px!important;} 新应用进程
ART 代码 (共享)
Framework 类库 (共享)
系统资源 (共享)
Heap (私有)

(仅此处为新拷贝)

新应用进程

ART 代码 (共享)
Framework 类库 (共享)
系统资源 (共享)
Heap (共享)

Zygote 进程

ART 虚拟机代码 (只读)
Framework 类库 (只读)
系统资源 (只读)
Heap (可写)
fork() 瞬间
应用开始修改数据 (COW 触发)

深度解析:Copy-On-Write (COW) 的底层机制
  1. Page Table 复制fork() 系统调用发生时,内核并不立即复制父进程(Zygote)的物理内存页,而是复制父进程的页表(Page Table)。此时,父子进程指向完全相同的物理内存地址。
  2. 权限降级 :内核将这些共享的物理内存页标记为只读(Read-Only)
  3. 写时触发异常 :当子进程(新应用)尝试向 Heap 写入数据时,MMU(内存管理单元)检测到对只读页的写操作,触发 Page Fault(缺页中断)
  4. 物理拷贝:内核捕获该中断,为该页分配新的物理内存,将数据从父进程的页复制到新页,并将子进程的页表指向新页。此后,父子进程各自拥有独立的副本。

学术定义 :COW 是一种惰性优化策略。它假设子进程可能不会修改大部分数据(如代码段、资源),从而避免不必要的内存拷贝开销。


3. Low Memory Killer (LMK) 机制

Android 没有 Swap 交换空间,当内存耗尽时,必须杀掉进程。LMK 是 Android 定制的 OOM Killer 变体。

3.1 进程优先级(oom_adj)体系

系统根据进程所处的状态(前台、后台、服务等)为其打分。分数越低,越不容易被杀。

进程类别 oom_adj 值 说明
前台进程 (Foreground) 0 正在与用户交互,最不容易被杀。
可见进程 (Visible) 1 可见但不在前台(如弹窗后的 Activity)。
服务进程 (Service) 2 - 5 运行着 Service,执行后台任务。
缓存进程 (Cached) 9 - 15 后台应用,随时可被回收以释放内存。
空进程 (Empty) 15 不含任何组件,仅作缓存,最先被杀。

3.2 LMK 工作流程

#mermaid-svg-1IF9qPgOTJ2PAKd1{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-1IF9qPgOTJ2PAKd1 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .error-icon{fill:#552222;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .marker.cross{stroke:#333333;}#mermaid-svg-1IF9qPgOTJ2PAKd1 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-1IF9qPgOTJ2PAKd1 p{margin:0;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .cluster-label text{fill:#333;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .cluster-label span{color:#333;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .cluster-label span p{background-color:transparent;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .label text,#mermaid-svg-1IF9qPgOTJ2PAKd1 span{fill:#333;color:#333;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .node rect,#mermaid-svg-1IF9qPgOTJ2PAKd1 .node circle,#mermaid-svg-1IF9qPgOTJ2PAKd1 .node ellipse,#mermaid-svg-1IF9qPgOTJ2PAKd1 .node polygon,#mermaid-svg-1IF9qPgOTJ2PAKd1 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .rough-node .label text,#mermaid-svg-1IF9qPgOTJ2PAKd1 .node .label text,#mermaid-svg-1IF9qPgOTJ2PAKd1 .image-shape .label,#mermaid-svg-1IF9qPgOTJ2PAKd1 .icon-shape .label{text-anchor:middle;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .rough-node .label,#mermaid-svg-1IF9qPgOTJ2PAKd1 .node .label,#mermaid-svg-1IF9qPgOTJ2PAKd1 .image-shape .label,#mermaid-svg-1IF9qPgOTJ2PAKd1 .icon-shape .label{text-align:center;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .node.clickable{cursor:pointer;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .arrowheadPath{fill:#333333;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-1IF9qPgOTJ2PAKd1 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-1IF9qPgOTJ2PAKd1 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-1IF9qPgOTJ2PAKd1 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .cluster text{fill:#333;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .cluster span{color:#333;}#mermaid-svg-1IF9qPgOTJ2PAKd1 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-1IF9qPgOTJ2PAKd1 rect.text{fill:none;stroke-width:0;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .icon-shape,#mermaid-svg-1IF9qPgOTJ2PAKd1 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .icon-shape p,#mermaid-svg-1IF9qPgOTJ2PAKd1 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .icon-shape .label rect,#mermaid-svg-1IF9qPgOTJ2PAKd1 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-1IF9qPgOTJ2PAKd1 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-1IF9qPgOTJ2PAKd1 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-1IF9qPgOTJ2PAKd1 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Linux 内核层
检测可用内存


内存监控线程
可用内存 < 阈值?
遍历进程列表
按 oom_adj 排序
选择 oom_adj 最大且内存占用大的进程
发送 SIGKILL 信号

深度解析:LMK 的阈值与计算

LMK 的决策基于两个核心参数:

  1. oom_adj:由 Framework 层根据进程状态计算得出(见下表)。
  2. minfree:内核预设的内存阈值。

oom_adj 计算逻辑(Framework 层)

Framework 通过 computeOomAdjLocked 计算进程的 oomScore

判定条件 权重影响 学术解释
是否有 Activity 在前台 Adj = 0 用户正在操作的进程,赋予最高优先级
是否有 Activity 可见 Adj = 1 虽不可操作,但对用户体验至关重要
是否正在运行 Foreground Service Adj = 0 或 1 执行用户感知的后台任务(如下载、播放音乐)
是否含有 ContentProvider Adj -= 2 (加权) 由于可能被其他进程调用,适当提高优先级
是否在后台运行超过 30 分钟 Adj += 5 长时间后台进程,降低优先级

minfree 阈值配置(内核层)

在 Android 系统中,LMK 的杀戮阈值是预设的(不同设备厂商可能微调):

复制代码
# 示例:当剩余内存低于以下数值时,杀掉对应 adj 的进程
/sys/module/lowmemorykiller/parameters/minfree
18432,23040,27648,32256,36864,41472  (单位: Page / 4KB)

# 对应的 adj 分数
/sys/module/lowmemorykiller/parameters/adj
0,100,200,300,900,906

4. 关键代码与数据结构(学术定义)

4.1 Zygote 启动参数(Init 脚本定义)

rc 复制代码
# system/core/rootdir/init.rc
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
    class main
    priority -20
    user root
    group root readproc reserved_disk
    socket zygote stream 660 root system
    socket usap_pool_primary stream 660 root system

4.2 ProcessRecord 中的 adj 计算逻辑

Framework 层通过 computeOomAdjLocked 计算进程的 oomScore

判定条件 权重影响
是否有 Activity 在前台 Adj = 0
是否有 Activity 可见 Adj = 1
是否正在运行 Foreground Service Adj = 0 或 1
是否含有 ContentProvider Adj -= 2 (加权)
是否在后台运行超过 30 分钟 Adj += 5

5. 本篇总结(知识闭环)

关键点 纯学术定义
Zygote 的本质 一个预加载了 ART 虚拟机和 Framework 资源的父进程,作为所有应用进程的模板。
Fork 的本质 利用 Linux 的 fork() 系统调用,配合 Copy-On-Write 技术,实现进程的快速克隆。
LMK 的本质 位于 Linux 内核层的守护进程,依据 oom_adj 分数决定在内存压力下杀死哪个进程。
应用启动的本质 不是创建新进程,而是 Zygote 进程的分裂与特化。

下一篇预告第一板块:Android 系统基石与运行原理 | 第五篇:Context 上下文与资源配置体系

相关推荐
JohnnyDeng941 小时前
【Android】RecyclerView性能优化与缓存机制:从卡顿到丝滑的完整指南
android·性能优化·kotlin·mvvm
zfoo-framework1 小时前
kotlin中体会到一些比较好用的点
android·开发语言·kotlin
●VON3 小时前
AtomGit Flutter鸿蒙客户端:文件树与代码浏览
android·服务器·安全·flutter·harmonyos·鸿蒙
故渊at10 小时前
系列三:组件化与模块化进阶 | 第11篇 组件化项目规范与问题根治:依赖、资源、Manifest 与混淆的全链路管控
android·架构·mvvm·模块化·组件化
故渊at10 小时前
系列二:MVVM 深度实战与项目重构 | 第7篇 LiveData & StateFlow 状态管理实战:从“粘包弹”到“丝滑流式”
android·重构
是阿建吖!10 小时前
【Linux】信号
android·linux·c语言·c++
alexhilton12 小时前
AppFunctions:让你的Android应用更容易被AI智能体发现
android·kotlin·android jetpack
qq36219670512 小时前
APK文件签名校验教程:验证APK真伪的完整方法
android·智能手机
赏金术士12 小时前
Android 组件化概念和特征
android·kotlin·组件化