第1章 引言
依据Jones、Hosking与Moss《垃圾回收算法手册》2012版、2016中文译本完整目录独立重构:建立显式释放与自动内存管理的共同评价框架,区分安全性、完整性、及时性、吞吐、停顿、空间和可移植性
第1章 引言
本页对应第一版正式结构中的 第1章 引言。课程不复制原文,而是按目录逐节点独立重构算法、证明与工程接口,目标是建立显式释放与自动内存管理的共同评价框架,区分安全性、完整性、及时性、吞吐、停顿、空间和可移植性。每项结论必须回到对象图、状态转换、伪代码和可重复测量,不能用某个JVM参数名称替代算法理解。
可验收学习目标
学习目标
- 能解释本页全部24个正式节点的对象图、状态转换、正确性条件和性能代价。
- 能实现或手工重放“给同一工作负载分别配置显式释放、追踪回收和引用计数模型,记录错误面、时间、峰值空间与尾延迟”,保存输入、原始输出和停止条件。
- 能比较安全性、完整性、及时性、吞吐、尾延迟、空间与实现复杂度,不用单指标下结论。
- 能设计至少一个会推翻当前选择的反例,并用对象图与根集合标注、指标口径表、实验方法卡、术语与记号对照完成独立交接。
首要陷阱是“把回收器比较缩成单次最大停顿,遗漏吞吐、空间、完整性、提示性和语言语义”。先预测,再执行;任何算法选择都必须说明对象是否移动、何时与变异器并发、需要多少备用空间、怎样处理根与跨区引用,以及失败时如何退化或回滚。
官方目录逐节点复刻
第1章 引言
正式节点 1/24。 从根集合、对象图、分配状态和回收阶段四层解释“第1章 引言”。先写出安全性或进展不变式,再标注实现所需的元数据、读写屏障和空间余量;最后用固定工作负载记录原始证据。该节点服务于“建立显式释放与自动内存管理的共同评价框架,区分安全性、完整性、及时性、吞吐、停顿、空间和可移植性”,不能只保留术语定义。
验证时先预测改变存活率、分配率、对象大小、线程数或堆余量后会发生什么,再只改变一个变量。若结果与预测相反,应检查根枚举、对象移动、缓存与同步、并发交错和测量窗口,而不是删掉反例。
1.1 显式释放
正式节点 2/24。 从根集合、对象图、分配状态和回收阶段四层解释“1.1 显式释放”。先写出安全性或进展不变式,再标注实现所需的元数据、读写屏障和空间余量;最后用固定工作负载记录原始证据。该节点服务于“建立显式释放与自动内存管理的共同评价框架,区分安全性、完整性、及时性、吞吐、停顿、空间和可移植性”,不能只保留术语定义。
验证时先预测改变存活率、分配率、对象大小、线程数或堆余量后会发生什么,再只改变一个变量。若结果与预测相反,应检查根枚举、对象移动、缓存与同步、并发交错和测量窗口,而不是删掉反例。
1.2 自动动态内存管理
正式节点 3/24。 从根集合、对象图、分配状态和回收阶段四层解释“1.2 自动动态内存管理”。先写出安全性或进展不变式,再标注实现所需的元数据、读写屏障和空间余量;最后用固定工作负载记录原始证据。该节点服务于“建立显式释放与自动内存管理的共同评价框架,区分安全性、完整性、及时性、吞吐、停顿、空间和可移植性”,不能只保留术语定义。
验证时先预测改变存活率、分配率、对象大小、线程数或堆余量后会发生什么,再只改变一个变量。若结果与预测相反,应检查根枚举、对象移动、缓存与同步、并发交错和测量窗口,而不是删掉反例。
1.3 比较垃圾回收算法
正式节点 4/24。 从根集合、对象图、分配状态和回收阶段四层解释“1.3 比较垃圾回收算法”。先写出安全性或进展不变式,再标注实现所需的元数据、读写屏障和空间余量;最后用固定工作负载记录原始证据。该节点服务于“建立显式释放与自动内存管理的共同评价框架,区分安全性、完整性、及时性、吞吐、停顿、空间和可移植性”,不能只保留术语定义。
验证时先预测改变存活率、分配率、对象大小、线程数或堆余量后会发生什么,再只改变一个变量。若结果与预测相反,应检查根枚举、对象移动、缓存与同步、并发交错和测量窗口,而不是删掉反例。
安全性
正式节点 5/24。 从根集合、对象图、分配状态和回收阶段四层解释“安全性”。先写出安全性或进展不变式,再标注实现所需的元数据、读写屏障和空间余量;最后用固定工作负载记录原始证据。该节点服务于“建立显式释放与自动内存管理的共同评价框架,区分安全性、完整性、及时性、吞吐、停顿、空间和可移植性”,不能只保留术语定义。
验证时先预测改变存活率、分配率、对象大小、线程数或堆余量后会发生什么,再只改变一个变量。若结果与预测相反,应检查根枚举、对象移动、缓存与同步、并发交错和测量窗口,而不是删掉反例。
吞吐量
正式节点 6/24。 从根集合、对象图、分配状态和回收阶段四层解释“吞吐量”。先写出安全性或进展不变式,再标注实现所需的元数据、读写屏障和空间余量;最后用固定工作负载记录原始证据。该节点服务于“建立显式释放与自动内存管理的共同评价框架,区分安全性、完整性、及时性、吞吐、停顿、空间和可移植性”,不能只保留术语定义。
验证时先预测改变存活率、分配率、对象大小、线程数或堆余量后会发生什么,再只改变一个变量。若结果与预测相反,应检查根枚举、对象移动、缓存与同步、并发交错和测量窗口,而不是删掉反例。
完整性与及时性
正式节点 7/24。 从根集合、对象图、分配状态和回收阶段四层解释“完整性与及时性”。先写出安全性或进展不变式,再标注实现所需的元数据、读写屏障和空间余量;最后用固定工作负载记录原始证据。该节点服务于“建立显式释放与自动内存管理的共同评价框架,区分安全性、完整性、及时性、吞吐、停顿、空间和可移植性”,不能只保留术语定义。
验证时先预测改变存活率、分配率、对象大小、线程数或堆余量后会发生什么,再只改变一个变量。若结果与预测相反,应检查根枚举、对象移动、缓存与同步、并发交错和测量窗口,而不是删掉反例。
停顿时间
正式节点 8/24。 从根集合、对象图、分配状态和回收阶段四层解释“停顿时间”。先写出安全性或进展不变式,再标注实现所需的元数据、读写屏障和空间余量;最后用固定工作负载记录原始证据。该节点服务于“建立显式释放与自动内存管理的共同评价框架,区分安全性、完整性、及时性、吞吐、停顿、空间和可移植性”,不能只保留术语定义。
验证时先预测改变存活率、分配率、对象大小、线程数或堆余量后会发生什么,再只改变一个变量。若结果与预测相反,应检查根枚举、对象移动、缓存与同步、并发交错和测量窗口,而不是删掉反例。
空间开销
正式节点 9/24。 从根集合、对象图、分配状态和回收阶段四层解释“空间开销”。先写出安全性或进展不变式,再标注实现所需的元数据、读写屏障和空间余量;最后用固定工作负载记录原始证据。该节点服务于“建立显式释放与自动内存管理的共同评价框架,区分安全性、完整性、及时性、吞吐、停顿、空间和可移植性”,不能只保留术语定义。
验证时先预测改变存活率、分配率、对象大小、线程数或堆余量后会发生什么,再只改变一个变量。若结果与预测相反,应检查根枚举、对象移动、缓存与同步、并发交错和测量窗口,而不是删掉反例。
针对特定语言的优化
正式节点 10/24。 从根集合、对象图、分配状态和回收阶段四层解释“针对特定语言的优化”。先写出安全性或进展不变式,再标注实现所需的元数据、读写屏障和空间余量;最后用固定工作负载记录原始证据。该节点服务于“建立显式释放与自动内存管理的共同评价框架,区分安全性、完整性、及时性、吞吐、停顿、空间和可移植性”,不能只保留术语定义。
验证时先预测改变存活率、分配率、对象大小、线程数或堆余量后会发生什么,再只改变一个变量。若结果与预测相反,应检查根枚举、对象移动、缓存与同步、并发交错和测量窗口,而不是删掉反例。
可伸缩性与可移植性
正式节点 11/24。 从根集合、对象图、分配状态和回收阶段四层解释“可伸缩性与可移植性”。先写出安全性或进展不变式,再标注实现所需的元数据、读写屏障和空间余量;最后用固定工作负载记录原始证据。该节点服务于“建立显式释放与自动内存管理的共同评价框架,区分安全性、完整性、及时性、吞吐、停顿、空间和可移植性”,不能只保留术语定义。
验证时先预测改变存活率、分配率、对象大小、线程数或堆余量后会发生什么,再只改变一个变量。若结果与预测相反,应检查根枚举、对象移动、缓存与同步、并发交错和测量窗口,而不是删掉反例。
1.4 性能劣势?
正式节点 12/24。 从根集合、对象图、分配状态和回收阶段四层解释“1.4 性能劣势?”。先写出安全性或进展不变式,再标注实现所需的元数据、读写屏障和空间余量;最后用固定工作负载记录原始证据。该节点服务于“建立显式释放与自动内存管理的共同评价框架,区分安全性、完整性、及时性、吞吐、停顿、空间和可移植性”,不能只保留术语定义。
验证时先预测改变存活率、分配率、对象大小、线程数或堆余量后会发生什么,再只改变一个变量。若结果与预测相反,应检查根枚举、对象移动、缓存与同步、并发交错和测量窗口,而不是删掉反例。
1.5 实验方法
正式节点 13/24。 从根集合、对象图、分配状态和回收阶段四层解释“1.5 实验方法”。先写出安全性或进展不变式,再标注实现所需的元数据、读写屏障和空间余量;最后用固定工作负载记录原始证据。该节点服务于“建立显式释放与自动内存管理的共同评价框架,区分安全性、完整性、及时性、吞吐、停顿、空间和可移植性”,不能只保留术语定义。
验证时先预测改变存活率、分配率、对象大小、线程数或堆余量后会发生什么,再只改变一个变量。若结果与预测相反,应检查根枚举、对象移动、缓存与同步、并发交错和测量窗口,而不是删掉反例。
1.6 术语与记号
正式节点 14/24。 从根集合、对象图、分配状态和回收阶段四层解释“1.6 术语与记号”。先写出安全性或进展不变式,再标注实现所需的元数据、读写屏障和空间余量;最后用固定工作负载记录原始证据。该节点服务于“建立显式释放与自动内存管理的共同评价框架,区分安全性、完整性、及时性、吞吐、停顿、空间和可移植性”,不能只保留术语定义。
验证时先预测改变存活率、分配率、对象大小、线程数或堆余量后会发生什么,再只改变一个变量。若结果与预测相反,应检查根枚举、对象移动、缓存与同步、并发交错和测量窗口,而不是删掉反例。
堆
正式节点 15/24。 从根集合、对象图、分配状态和回收阶段四层解释“堆”。先写出安全性或进展不变式,再标注实现所需的元数据、读写屏障和空间余量;最后用固定工作负载记录原始证据。该节点服务于“建立显式释放与自动内存管理的共同评价框架,区分安全性、完整性、及时性、吞吐、停顿、空间和可移植性”,不能只保留术语定义。
验证时先预测改变存活率、分配率、对象大小、线程数或堆余量后会发生什么,再只改变一个变量。若结果与预测相反,应检查根枚举、对象移动、缓存与同步、并发交错和测量窗口,而不是删掉反例。
变异器与回收器
正式节点 16/24。 从根集合、对象图、分配状态和回收阶段四层解释“变异器与回收器”。先写出安全性或进展不变式,再标注实现所需的元数据、读写屏障和空间余量;最后用固定工作负载记录原始证据。该节点服务于“建立显式释放与自动内存管理的共同评价框架,区分安全性、完整性、及时性、吞吐、停顿、空间和可移植性”,不能只保留术语定义。
验证时先预测改变存活率、分配率、对象大小、线程数或堆余量后会发生什么,再只改变一个变量。若结果与预测相反,应检查根枚举、对象移动、缓存与同步、并发交错和测量窗口,而不是删掉反例。
变异器根
正式节点 17/24。 从根集合、对象图、分配状态和回收阶段四层解释“变异器根”。先写出安全性或进展不变式,再标注实现所需的元数据、读写屏障和空间余量;最后用固定工作负载记录原始证据。该节点服务于“建立显式释放与自动内存管理的共同评价框架,区分安全性、完整性、及时性、吞吐、停顿、空间和可移植性”,不能只保留术语定义。
验证时先预测改变存活率、分配率、对象大小、线程数或堆余量后会发生什么,再只改变一个变量。若结果与预测相反,应检查根枚举、对象移动、缓存与同步、并发交错和测量窗口,而不是删掉反例。
引用、字段与地址
正式节点 18/24。 从根集合、对象图、分配状态和回收阶段四层解释“引用、字段与地址”。先写出安全性或进展不变式,再标注实现所需的元数据、读写屏障和空间余量;最后用固定工作负载记录原始证据。该节点服务于“建立显式释放与自动内存管理的共同评价框架,区分安全性、完整性、及时性、吞吐、停顿、空间和可移植性”,不能只保留术语定义。
验证时先预测改变存活率、分配率、对象大小、线程数或堆余量后会发生什么,再只改变一个变量。若结果与预测相反,应检查根枚举、对象移动、缓存与同步、并发交错和测量窗口,而不是删掉反例。
活性、正确性与可达性
正式节点 19/24。 从根集合、对象图、分配状态和回收阶段四层解释“活性、正确性与可达性”。先写出安全性或进展不变式,再标注实现所需的元数据、读写屏障和空间余量;最后用固定工作负载记录原始证据。该节点服务于“建立显式释放与自动内存管理的共同评价框架,区分安全性、完整性、及时性、吞吐、停顿、空间和可移植性”,不能只保留术语定义。
验证时先预测改变存活率、分配率、对象大小、线程数或堆余量后会发生什么,再只改变一个变量。若结果与预测相反,应检查根枚举、对象移动、缓存与同步、并发交错和测量窗口,而不是删掉反例。
伪代码
正式节点 20/24。 从根集合、对象图、分配状态和回收阶段四层解释“伪代码”。先写出安全性或进展不变式,再标注实现所需的元数据、读写屏障和空间余量;最后用固定工作负载记录原始证据。该节点服务于“建立显式释放与自动内存管理的共同评价框架,区分安全性、完整性、及时性、吞吐、停顿、空间和可移植性”,不能只保留术语定义。
验证时先预测改变存活率、分配率、对象大小、线程数或堆余量后会发生什么,再只改变一个变量。若结果与预测相反,应检查根枚举、对象移动、缓存与同步、并发交错和测量窗口,而不是删掉反例。
分配器
正式节点 21/24。 从根集合、对象图、分配状态和回收阶段四层解释“分配器”。先写出安全性或进展不变式,再标注实现所需的元数据、读写屏障和空间余量;最后用固定工作负载记录原始证据。该节点服务于“建立显式释放与自动内存管理的共同评价框架,区分安全性、完整性、及时性、吞吐、停顿、空间和可移植性”,不能只保留术语定义。
验证时先预测改变存活率、分配率、对象大小、线程数或堆余量后会发生什么,再只改变一个变量。若结果与预测相反,应检查根枚举、对象移动、缓存与同步、并发交错和测量窗口,而不是删掉反例。
变异器读写操作
正式节点 22/24。 从根集合、对象图、分配状态和回收阶段四层解释“变异器读写操作”。先写出安全性或进展不变式,再标注实现所需的元数据、读写屏障和空间余量;最后用固定工作负载记录原始证据。该节点服务于“建立显式释放与自动内存管理的共同评价框架,区分安全性、完整性、及时性、吞吐、停顿、空间和可移植性”,不能只保留术语定义。
验证时先预测改变存活率、分配率、对象大小、线程数或堆余量后会发生什么,再只改变一个变量。若结果与预测相反,应检查根枚举、对象移动、缓存与同步、并发交错和测量窗口,而不是删掉反例。
原子操作
正式节点 23/24。 从根集合、对象图、分配状态和回收阶段四层解释“原子操作”。先写出安全性或进展不变式,再标注实现所需的元数据、读写屏障和空间余量;最后用固定工作负载记录原始证据。该节点服务于“建立显式释放与自动内存管理的共同评价框架,区分安全性、完整性、及时性、吞吐、停顿、空间和可移植性”,不能只保留术语定义。
验证时先预测改变存活率、分配率、对象大小、线程数或堆余量后会发生什么,再只改变一个变量。若结果与预测相反,应检查根枚举、对象移动、缓存与同步、并发交错和测量窗口,而不是删掉反例。
集合、多重集、序列与元组
正式节点 24/24。 从根集合、对象图、分配状态和回收阶段四层解释“集合、多重集、序列与元组”。先写出安全性或进展不变式,再标注实现所需的元数据、读写屏障和空间余量;最后用固定工作负载记录原始证据。该节点服务于“建立显式释放与自动内存管理的共同评价框架,区分安全性、完整性、及时性、吞吐、停顿、空间和可移植性”,不能只保留术语定义。
验证时先预测改变存活率、分配率、对象大小、线程数或堆余量后会发生什么,再只改变一个变量。若结果与预测相反,应检查根枚举、对象移动、缓存与同步、并发交错和测量窗口,而不是删掉反例。
从对象图与不变式开始
自动管理首先是一项语义合同:程序仍可能使用的对象不能被回收,永久不可达对象最终应被识别,但二者并不自动规定何时回收、是否移动以及停顿上限。显式释放把所有权证明交给程序员,GC则把可达性近似、根枚举和空间再利用交给运行时。实验必须把变异器完成的有效工作作为分母,并同时报告回收周期、峰值驻留集、分配速率和分位停顿。
所有垃圾回收问题先抽象为↡以对象为顶点、引用为有向边并显式标出根的运行时状态模型。↡运行时承诺可由栈、寄存器、全局、句柄或原生接口直接访问的入口集合是遍历入口;从根可达只是保守的存活近似,并不等于对象未来必被使用。↡执行应用逻辑、分配对象并持续改变对象图的线程与回收器共享同一堆状态。安全性要求不能回收仍可能被访问的对象,完整性描述是否能找出所有垃圾,及时性描述识别与回收之间的延迟。回收器、分配器、编译器和语言语义共同决定这些合同,任何一层缺失都可能让局部正确的算法在系统中失效。
停止世界、并行和并发是三个正交维度。停止世界描述变异器是否暂停,并行描述多个回收线程是否同时完成同一阶段,并发描述回收器是否与变异器重叠运行。并发降低某些暂停,却增加屏障、同步、浮动垃圾和CPU竞争;并行缩短阶段墙钟时间,却可能增加总CPU和内存带宽。必须报告阶段时间线,而不是把“并行并发”当成一个模糊标签。
对象移动决定运行时接口的复杂度。不移动方案保留地址稳定性但可能碎片化;复制与整理产生连续空间和快速分配,却必须更新根、堆内引用、句柄、内部指针和原生代码持有的地址。并发移动还需读屏障、间接层或多版本协议,保证变异器无论在搬移前、中、后读取都看到合法对象身份与字段值。↡回收完成前用于吸收继续分配、对象复制和元数据增长的保留容量必须按最坏工作量而不是平均值估算;并发结构还要指出↡一个并发操作可被视为瞬间生效、并与其他操作形成合法顺序的时刻。
最小算法切片
先把算法写成可检查的状态机,而不是产品参数清单:
roots -> discover(object)
while worklist is not empty:
object = remove(worklist)
for each reference in object:
if reference has not been discovered:
mark or forward reference
add reference to worklist
reclaim, sweep, compact, or publish the completed space实现记录至少包含对象标识、地址或句柄、颜色/计数/年龄、所属分区、扫描状态和转发状态。每次状态变化注明唯一所有者和原子边界;若元数据会溢出、工作表会耗尽或目的空间会不足,失败路径必须在实验前定义。只给出正常路径的伪代码不能证明回收器可用。
实验输入与环境采用可重放合同:
runtime: exact-build-and-commit
heap: fixed-min-max-and-region-layout
workload: seeded-object-graph-and-allocation-trace
controls: one-variable-per-run
evidence: raw-events-percentiles-space-cpu-errors
stop: timeout-or-explicit-safety-limit验收把预期和可推翻条件写在运行前:
Given identical roots, object graph, heap limit, threads, and seed
When one collector policy or workload variable changes
Then safety and progress invariants still hold
And target gains do not hide CPU, space, latency, or failure regressions对并发算法,枚举变异器可能执行的读、写、分配、发布、批量复制、原生调用和线程退出。屏障完整性要逐项核对,阶段切换前冲刷线程本地日志;终止检测不仅检查全局队列为空,还要证明没有本地或飞行中的工作。对实时算法,还要把每步最大成本和不可中断区间写进预算。
定量模型与边界
回收占比与有效吞吐必须共用同一墙钟窗口:
追踪与复制工作至少受根、扫描边和存活字节控制:
空间安全要求回收完成前仍有足够余量吸收分配和疏散:
实时与低延迟比较还应明确一个观测窗内留给变异器的最低份额:
公式用于明确变量,不替代测量。每个数字注明单位、堆上限、对象分布、线程数、预热、重复次数、分位数和置信范围。平均暂停、最大暂停和服务端请求尾延迟回答不同问题;一次运行的最小值不能作为容量承诺。
本章回顾
本页从“第1章 引言”覆盖到“集合、多重集、序列与元组”,共24个正式节点。闭环是先建立对象图与不变式,再执行“给同一工作负载分别配置显式释放、追踪回收和引用计数模型,记录错误面、时间、峰值空间与尾延迟”,最后用对象图与根集合标注、指标口径表、实验方法卡、术语与记号对照证明结论可重放、可推翻、可回滚。若仍出现“把回收器比较缩成单次最大停顿,遗漏吞吐、空间、完整性、提示性和语言语义”,应补做失败交错和空间余量实验,而不是继续叠加参数。
练习
问题 1:第1章 引言覆盖哪些正式节点,核心证明主线是什么?
问题 2:怎样为第1章 引言建立最小可执行实验?
问题 3:为什么“把回收器比较缩成单次最大停顿,遗漏吞吐、空间、完整性、提示性和语言语义”会破坏结论?
问题 4:如何为第1章 引言设计反证?
问题 5:把该章算法迁移到另一语言或运行时时,哪些合同必须重建?
问题 6:达到独立交接标准需要哪些证据?
名词解释
本章出现的专业名词,用大白话再讲一遍。
- 对象图
- 以对象为顶点、引用为有向边并显式标出根的运行时状态模型。
- 根集合
- 运行时承诺可由栈、寄存器、全局、句柄或原生接口直接访问的入口集合。
- 变异器
- 执行应用逻辑并改变对象图的程序线程。
- 空间余量
- 回收完成前承接继续分配、复制与元数据所需的保留空间。
- 线性化点
- 一个并发操作可被视为瞬间生效、并与其他操作形成合法顺序的时刻。