为什么Go语言可以将GC暂停时间降低到1ms以下,而JVM却不能?

mlnl4t2r  于 2022-11-07  发布在  Go
关注(0)|答案(2)|浏览(364)

所以这就是:https://groups.google.com/forum/?fromgroups#!topic/golang-dev/Ab1sFeoZg_8:
今天,我提交了一些修改,使最坏情况下停止世界的时间小于100微秒,这对于那些有很多活跃goroutine的应用程序来说尤其有效,因为在以前,这些应用程序的暂停时间可能会大大增加。
高GC暂停是JVM用户长期困扰的问题之一。
什么(架构?)约束阻止JVM将GC暂停降低到Go级别,但不影响Go?

c9qzyr3d

c9qzyr3d1#

2021年更新:使用OpenJDK 16,ZGC现在有了max pause time of <1ms and average pause times 50µs

与Go语言的收集器不同,它在实现这些目标的同时仍然执行压缩。

更新:在OpenJDK 17中,Shenandoah利用了由ZGC和achieves similar results引入的相同技术。

阻止JVM将GC暂停降低到golang级别的(体系结构)约束是什么
由于低停顿GC已经存在了一段时间(见下文),因此没有任何基本的差异,所以这可能更多的是来自历史经验或开箱即用配置的印象差异,而不是可能的情况。
高GC暂停是JVM用户长期困扰的问题之一。
稍微搜索一下,就会发现java也有类似的解决方案。

openjdk中的其他收集器与Go语言不同,是压缩分代收集器。这是为了避免碎片问题,并通过启用碰撞指针分配和减少在GC中花费的CPU时间,在具有大堆的服务器级机器上提供更高的吞吐量。至少在良好的条件下,CMS可以实现单位数毫秒的暂停,尽管它与一个移动的年轻一代收集器配对。
Go语言的收集器是非分代的、非压缩的,并且需要写屏障(参见other SO question),这导致了更低的吞吐量/更多的CPU开销用于收集,更高的内存占用(由于碎片和需要更多的空间),以及更低的缓存效率的对象在堆上的放置(非压缩内存布局)。
因此,GoGC主要针对暂停时间进行了优化,同时保持相对简单(按照GC标准),这是以牺牲其他几个性能和可伸缩性目标为代价的。JVM GC做出了不同的权衡。旧的GC通常关注吞吐量。最近的GC以更高的复杂性为代价实现了低暂停时间和其他几个目标。

lp0sw83n

lp0sw83n2#

根据这个演示Getting to Go: The Journey of Go's Garbage Collector,Go语言的收集器只利用了堆的一半来存储实时数据:
堆2X活动堆
我的印象是,JavaGC通常以更高的堆利用率为目标,因此它们在这里做出了非常不同的权衡。

相关问题