【问题标题】:How does CLR GC compare to latest ZGC and Shenandoah GC on JVM?CLR GC 与最新的 ZGC 和 JVM 上的 Shenandoah GC 相比如何?
【发布时间】:2021-01-22 21:56:57
【问题描述】:

近年来,许多特性被添加到 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 毫秒相比,平均 STW 大约 20-30 毫秒,偶尔跳到 300+ 毫秒看起来真的很糟糕(正如 GC 制造商声称和测试的那样)确认)在 JVM 上暂停。

我必须说这让我有点担心,因为有一大堆应用程序的 GC 暂停很重要。事实上,它们是决定特定技术(例如 .NET、JVM、本机等)是否应被视为对任务或目的可行的关键因素之一。看起来 JVM 上的最新 GC 为 Java 和其他 JVM 语言/技术开辟了新领域。我们不允许应用程序停止 500 毫秒左右的区域,因为 GC 必须完成它的工作,而最大约 10 毫秒,平均约 1 毫秒就足够了。

今天的真相是什么? CLR GC 与最新的 JVM GC 相比如何?是否有关于 CLR 上的 STW 暂停的任何保证(看起来 JVM 正在朝着这个方向发展)?

【问题讨论】:

  • ZGC 越来越好了。 JDK 16 的初步结果显示,在 3 TB 堆上的最大暂停时间不到 1 毫秒。 “有问题的 GC 暂停已成为过去”youtu.be/88E86quLmQA?t=1728

标签: c# .net garbage-collection jvm clr


【解决方案1】:

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

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

我们不允许应用程序停止的区域 500 毫秒左右,因为 GC 必须完成它的工作,而最大约 10 毫秒 平均约 1 毫秒就足够了。

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

【讨论】:

  • 你有一些好点,我只想说一个。在我 12 年的编码生涯中,我遇到了一个其他了解有关 java 垃圾收集器的基本知识的开发人员:它们是可配置的,但更多时候它们是开发人员可忽略的。跨度>
【解决方案2】:

由于固有的设计差异,JVM 的最新垃圾收集器很可能会大大优于 CLR。这背后的主要原因是默认情况下 CLR 处理内存稍好一些,而 JVM 确实受到了一些影响。因此,让 CLR 中的 GC 快速运行并没有太大的压力,因为简单的设计就足够了,而且做得很好。相比之下,JVM 确实需要更好的 GC,实际上可能拥有迄今为止最先进的 GC。尽管这可能不会使 JVM 比 CLR 快几个数量级,但如果您让它们的 GC 相互竞争,CLR 将根本没有机会,尤其是对于 Z 和 Shenandoah 等较新的 JVM GC。

【讨论】:

  • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多