CLR的垃圾收集器与JVM上的最新版本ZGC和Shenandoah GC有什么区别?

6
近年来,C#(在.NET世界中排名第一)新增了很多功能以减少GC压力。毫无疑问,所有这些功能都使我们能够构建更好、更高效的应用程序。但无论语言和VM(CLR、JVM)随时间添加了哪些功能,具有高性能和非阻塞GC仍然是托管应用程序的关键性能因素。
最近,在JVM世界中出现了两种新的GC,它们似乎提供了卓越的性能指标。有一些来源(包括作者)提供了有关这些GC的基准测试和技术见解。我们可以了解到,无论堆大小如何,最大STW(停止世界)间隔“承诺”不超过10毫秒,通常平均振荡在1毫秒以下。还有一些测试显示,新GC的开销平衡良好,不会对应用程序吞吐量产生负面影响,同时大幅度降低了(10倍或更多)STW暂停。
另一方面,CLR GC的信息很少。是否有最新的来源来查看CLR GC(4.8、Core 3.1、.NET 5)与最新的JVM成就相比如何?我能找到一些旧的来源讨论CLR GC与G1的比较。但是如今,G1无法与ZGC/Shenandoah相匹配,而旧的来源并不能展示现实情况。考虑到没有更新的来源,我们可能得出结论,CLR GC指标自那时以来并没有显著改善。但是,在2020年看来,这似乎是.NET平台的真正问题,因为与1毫秒平均值和10毫秒最大值(GC制造商声称并测试似乎证实的暂停)相比,平均STW约为20-30毫秒,并偶尔跳至300多毫秒,看起来非常糟糕。
我必须说,这让我有些担心,因为有很多应用程序,其中GC暂停非常重要。事实上,它们是决定指定技术(例如.NET、JVM、本机等)是否应该考虑用于任务或目的的关键因素之一。似乎在JVM上,最新的GC为Java和其他JVM语言/技术开辟了新的领域。在这些领域中,我们不允许应用程序因GC必须执行其工作而停止500ms左右,而~10ms的最大值和~1ms的平均值已经足够好了。
真相是什么?CLR GC与最新的JVM GC相比如何?CLR是否有关于STW暂停的任何保证(看起来JVM正在朝这个方向发展)?

ZGC变得越来越好了。JDK 16的初步结果显示,在3 TB堆上,最大暂停时间少于1毫秒。 "有问题的GC暂停已成过去" https://youtu.be/88E86quLmQA?t=1728 - Kire Haglin
2个回答

6

这是一个庞大的话题,但如果我不得不总结一下:

  • shenandoah、zgc等是低延迟垃圾收集器:它们为了确保非常低的暂停时间而牺牲吞吐量。它们适用于某些应用程序(基本上是任何具有低延迟约束的应用程序),但不适用于其他应用程序(以极端情况为例,对于批处理,您根本不关心延迟,并希望最大化吞吐量,这使得这些GC成为一个糟糕的选择)
  • 到目前为止,.NET没有低延迟GC。我听说有一些长期计划来实现它,但我怀疑我们在至少2年后才会看到任何结果
  • .NET GC的方法与Java GC大不相同。Java GC可以进行精细调整,但代价是巨大的复杂性。.NET GC旨在“只需工作”,设置很少,但易于理解和利用。这越来越不成立了,因为.NET Core添加了一堆配置旋钮,例如用于调整gen 0预算。

不允许应用程序停止500ms左右,因为GC必须执行其工作,而10ms左右的最大值,平均值为1ms左右就足够了。

根据我非代表性的经验,在使用.NET时,您可以期望每个gen 0收集器产生5到15毫秒的GC暂停时间。如果你的目标是约1毫秒,那么你可能需要完全禁用GC。我知道有一些公司正在使用.NET进行高频交易,所以这表明它是可行的。但只是因为他们可以在市场关闭之外重新启动服务器。如果您需要持续的约1毫秒暂停时间,则.NET还没有准备好。


你提出了一些很好的观点,我只想深入探讨其中一个。在我12年的编程经验中,我只遇到过另外一个开发人员知道Java垃圾收集器周围的基本事情:它们是可配置的,但更常见的是开发人员可以忽略它们。 - Eugene
能否创建一个开源的垃圾收集器来替换CLR的垃圾收集器呢? - undefined
1
@JohnNyingi 可能是可以的,但是这会是一段艰难的旅程。你可以使用 DOTNET_GCName 来要求 .NET 加载你自定义的 GC,但是这个 API 非常主观,并且反映了 .NET GC 的工作方式。如果要实现一个完全不同的 GC(例如,低延迟的 GC),我建议你分叉 CLR。 - undefined
@KevinGosse 很有趣,我对此感兴趣的原因是我想知道.Net是否能够获得类似ZGC或Azul C4的东西。 - undefined
1
@JohnNyingi 是的,从技术上讲,没有任何理由不能做到。更多的是要找到一个愿意花费数百小时来完成这项任务的领域专家。 - undefined

1
由于设计上的差异,JVM的最新垃圾回收器很可能会大大优于CLR的。主要原因是CLR默认处理内存略微更好,而JVM在这方面稍微有些不足。因此,没有太多压力使CLR中的GC变得非常快,因为简单的设计已经足够并且表现良好。相比之下,JVM确实需要更好的GC,事实上可能拥有迄今为止最先进的GC。虽然这可能不会使JVM比CLR快数个数量级,但如果将它们的GC相互对比,CLR将毫无机会,特别是像Z和Shenandoah这样的新型JVM GC。

1
你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心找到有关如何编写良好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接