README
# 第 4 卷|内存的真相
从虚拟内存到垃圾回收——理解程序运行的物理基础。
# 🎯 这一卷要回答什么
内存是程序员永远绕不开的话题。OOM、内存泄漏、Full GC、栈溢出、缓存命中率——你也许都见过,但能回答下面这些"为什么"吗?
- 为什么两个进程都拿到了
0x7fff...的地址却互不影响?虚拟内存到底"虚"在哪? - 为什么 Java / Go / Python 都有 GC,但实现完全不同? 三色标记、分代、ZGC、Tracing、引用计数究竟在权衡什么?
- 栈和堆——这两个名字几乎每个程序员都用过,但它们在 OS 层面真的是"两个独立的物理区域"吗?
- 为什么把数组遍历方向从行改成列,性能差 10 倍?Cache Line / 伪共享到底是什么?
- 强引用 / 软引用 / 弱引用 / 虚引用——为什么需要四种?没有的语言(如 Rust)是怎么应对的?
- 内存泄漏在 GC 语言里为什么依然普遍?Profiler 凭什么能"看到"分配?
- 深拷贝 vs 浅拷贝 vs Copy-on-Write——为什么 Linux 的 fork 用 COW?这个思想还能用在哪里?
第 4 卷不只讲 GC 算法,它讲"程序的物理基础如何决定语言的设计"。
# 📖 篇章总览(8 篇)
| 序号 | 文档 | 核心矛盾 |
|---|---|---|
| 4.1 | 虚拟内存与地址空间 | MMU / 页表 / TLB / COW —— 现代内存的根本骨架 |
| 4.2 | 内存模型技术设计 | 冯·诺依曼 → CPU cache → JMM 的演进 |
| 4.3 | 堆和栈内存的设计 | 栈帧、malloc、glibc chunk/bin 的设计哲学 |
| 4.4 | 内存对齐与缓存局部性 | Cache Line / Padding / 伪共享 —— 现代 CPU 的隐形税 |
| 4.5 | 内存回收机制设计 | 标记清除 → 复制 → 整理 → 分代 → ZGC |
| 4.6 | 多种引用技术设计 | 强 / 软 / 弱 / 虚引用的所有权语义对比 |
| 4.7 | 内存泄漏与诊断原理 | GC Roots / 支配树 / Heap Dump / Profiler 的工程原理 |
| 4.8 | 数据拷贝设计原理 | 浅 / 深 / 写时拷贝 —— 时间换空间的工程艺术 |
# 🔗 知识脉络
flowchart LR
A[4.1 虚拟内存<br/>地址空间的本质] --> B[4.2 内存模型<br/>读写一致性]
B --> C[4.3 堆栈<br/>分配两套机制]
C --> D[4.4 对齐与缓存<br/>性能的隐形约束]
D --> E[4.5 GC<br/>谁来回收]
E --> F[4.6 引用<br/>四种持有语义]
F --> G[4.7 泄漏诊断<br/>从看不见到看得见]
G --> H[4.8 拷贝<br/>不动还是动]
H -.闭环.-> A
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
虚拟内存决定"地址的语义",内存模型决定"读写顺序",堆栈决定"分配方式",对齐与缓存决定"访问效率",GC 决定"回收时机",引用决定"持有方式",泄漏诊断决定"问题可见性",拷贝决定"复制成本"——八个维度撑起内存生命周期的完整图景。
# 🌉 与其他卷的承接
- 承接第 2 卷:第 2 卷讲对象布局与调用栈,本卷讲对象在虚拟内存上的真实分布与回收。
- 承接第 3 卷:JMM 是并发原语的正确性基础——
volatile/synchronized都依赖内存模型语义;伪共享则与并发性能直接相关。 - 通往第 5 卷:跨进程通信(IPC)大量基于共享内存与零拷贝技术,本卷的虚拟内存与拷贝原理是其前置。
# 💡 学完你能回答
- 为什么 G1 / ZGC 都强调"低延迟"?老的 CMS 哪里不够好?
String.intern()触发的字符串常量池放在堆还是元空间?Java 7/8/11 有什么变化?- 为什么
WeakHashMap不能解决所有缓存问题?什么时候该用SoftReference? - Linux fork 一个 4GB 内存的进程为什么很快?什么时候才"真的拷贝"?
- 为什么生产环境常常关闭 Swap?OOM Killer 又是怎么挑选"祭品"的?
- 一次 Heap Dump 8GB,怎么从中找到内存泄漏的"真凶"?
- Rust 没有 GC,为什么内存安全性反而比 Java 更高?
# ⚠️ 学习侧重点
这一卷的特点是"算法 + 工程双重深度":
算法侧:GC 算法、引用计数、写屏障、读屏障、记忆集、支配树...
工程侧:JVM 调优、堆 Dump 分析、MAT、jstat、火焰图、内存泄漏定位...
1
2
2
建议:第一遍只读算法侧建立框架;第二遍带着自己项目里的 OOM 或 Full GC 案例回头读工程侧。
上次更新: 2026/06/07, 10:26:12