32 | 运行时(二):垃圾收集与语言的特性有关吗?
该思维导图由 AI 生成,仅供参考
垃圾收集算法概述
- 深入了解
- 翻译
- 解释
- 总结
垃圾收集算法是自动内存管理的核心,不同的算法有不同的特点。本文介绍了标记-清除、标记-整理、停止-拷贝、引用计数、分代收集、增量收集和并发收集等算法。其中,标记-清除算法从GC根节点出发,标记可达对象,清除垃圾;标记-整理算法在清除垃圾后整理内存,避免内存碎片;停止-拷贝算法将内存分为新旧空间,拷贝可达对象到新空间。Python采用引用计数算法,通过引用数判断对象是否为垃圾。文章还介绍了Python的内存管理特征和垃圾回收算法,以及其他语言和编译器采用引用计数的情况。编译器在配合引用计数算法时,需要生成相应的指令来做引用数的增减,并可以通过逃逸分析等优化算法提高程序性能。总体而言,本文涵盖了垃圾收集算法的核心原理和不同语言的应用情况,对于想要深入了解垃圾收集机制的读者具有很高的参考价值。 文章还介绍了其他语言如Java、JavaScript(V8)和Julia等的垃圾收集策略,它们通常采用分代收集的策略,针对新生代采用标记-清除或停止拷贝算法。相比引用计数算法,这些语言避免了引用计数的缺点,如增减引用计数所导致的计算量较大,在多线程情况下需要用到锁,以及可能导致内存碎片化和局部性差等问题。此外,文章还探讨了针对服务端程序开发的Java和Go语言在垃圾收集方面的需求,以及它们致力于减少垃圾收集导致的停顿时间的努力。最新的垃圾收集器已经使得垃圾收集导致的停顿降低到了几毫秒内。同时,文章解释了在垃圾收集时为何需要停下整个程序以及如何减少停顿时间的方法。 总的来说,本文深入探讨了垃圾收集算法的原理和不同语言的应用情况,对于想要了解垃圾收集机制的读者具有很高的参考价值。
《编译原理实战课》,新⼈⾸单¥59
全部留言(3)
- 最新
- 精选
- Tino's Park文章有几个问题请教下: 1. Go的GC目前为止(1.14.3)是非分代,非移动的并发算法(三色标记)算法,不是分代的; 2. 并发标记算法还有有一个问题,就是write-barrier在扫描期间,也需要一直运行,从而干扰业务的执行; 3. 关于STW,在大数据量下目前很难做到较优吧。
作者回复: 关于1,多谢指出,是我疏忽了。我查了一下,Go目前确实没有实现分代的gc算法。不过,Go似乎计划在未来实现一种“基于请求的回收算法(Request Oriented Collection,ROC),其实质也是某种分代算法:新对象及时回收。 关于2,多谢补充! 关于3,STW是GC的难点。GC又是实现现代语言的难点,目前很难有什么突破性的进展。如果我来实现一门新护眼,那么会采取几个办法来客服这个问题:1.在某些编程领域,根本性地避免gc,就像rust那样;2.像erlang那样,由于对运行机制做了限制,从而降低了gc的难度;3.采用引用计数的方法,就像Objective C、swift和方舟编译器那样,会比较均匀的让整个程序变慢,但不会突然STW。 https://docs.google.com/document/d/1gCsFxXamW8RRvOe5hECz98Ftk-tcRRJcDFANj2VwCB0/edit”
2020-09-1822 - D增加内置关键字支持不可变对象,比如像rust,Scala等语言。
作者回复: Great!不可变确实对垃圾收集有帮助。在39讲函数式编程中也会提到这一点。
2020-08-26 - 写点啥呢请问宫老师,增量收集算法,看上去是在增量做标记,这样可以尽量不打断程序的情况下完成标记(屏障代码会带来一定性能影响),不知道我的理解对么? 进而有个疑问,如果程序的对象变化非常频繁,导致增量过程一直无法完成(就是灰色集合始终不为空)那什么时候才能做内存回收释放呢?
作者回复: 并行收集是尽量不打断程序做收集,而增量收集是每次终端时间都尽量短。 你说的情况,确实体现了垃圾收集的复杂性,又要终端时间尽量短,又不要造成堆积,在两方面做好权衡。 对于你说的这种情况,要么增加每次暂停处理的量,要么就必须有一次较长时间的暂停,彻底做回收。
2020-08-26