知识卡片

非分代也有理由

普通读书笔记卡 · 1486.b

内容

(书中 Go 1.14)分代GC假设”多数垃圾是新创建对象”,但 Go 的逃逸分析已把会长期存活的对象提前放进堆,短命对象多留在栈上随函数退出自动回收,削弱了分代假设的优势;分代GC还需额外写屏障维护隔代关系、拖慢并发标记。GC 选型要结合逃逸分析等语言生态权衡,Go 曾尝试分代GC但最终放弃。

参考来源

- 位置:《Go语言底层原理剖析》第19章《垃圾回收初探》19.3.2节《为什么不选择分代GC?》 - 结论依据:原文明确"Go语言并不是没有尝试过分代GC。分代GC的主要假设是大部分变成垃圾的对象都是新创建的,但是由于编译器的优化,Go语言通过内存逃逸的机制将会继续使用的对象转移到了堆中,大部分生命周期很短的对象会在栈中分配……减弱了使用分代GC的优势。同时,分代GC需要额外的写屏障来保护并发垃圾回收时对象的隔代性,会减慢GC的速度。因此,分代GC是被尝试过并抛弃的方案",因此可以推出"Go 因逃逸分析改变了对象生命周期分布、且写屏障成本过高而放弃分代GC"的结论。 - 原始内容:分代GC指将对象按照存活时间进行划分。这种算法的重要前提是:死去的对象一般都是新创建不久的……Go语言并不是没有尝试过分代GC。分代GC的主要假设是大部分变成垃圾的对象都是新创建的,但是由于编译器的优化,Go语言通过内存逃逸的机制将会继续使用的对象转移到了堆中,大部分生命周期很短的对象会在栈中分配,这和其他使用分代GC的编程语言有显著的不同,减弱了使用分代GC的优势。同时,分代GC需要额外的写屏障来保护并发垃圾回收时对象的隔代性,会减慢GC的速度。因此,分代GC是被尝试过并抛弃的方案。