C# CLR GC与JVM上最新的ZGC和Shenandoah GC相比如何?

C# CLR GC与JVM上最新的ZGC和Shenandoah GC相比如何?,c#,.net,garbage-collection,jvm,clr,C#,.net,Garbage Collection,Jvm,Clr,近年来,C#(在.NET世界中排名第一的玩家)增加了许多功能,以减少GC压力。毫无疑问,所有这些功能都使我们能够构建更好、更高效的应用程序。但是,不管随着时间的推移添加了何种语言和VM(CLR、JVM)特性,性能良好且无阻塞的GC是托管应用程序的关键性能因素 最近在JVM世界中出现了两个新的GC,它们似乎提供了显著的指标。有一些来源(包括作者)提供了关于这些地面军事系统的基准和技术见解。我们可以了解到,最大STW(停止世界)间隔“被承诺”不再超过10毫秒,并且无论堆大小如何,通常平均振荡在1毫秒

近年来,C#(在.NET世界中排名第一的玩家)增加了许多功能,以减少GC压力。毫无疑问,所有这些功能都使我们能够构建更好、更高效的应用程序。但是,不管随着时间的推移添加了何种语言和VM(CLR、JVM)特性,性能良好且无阻塞的GC是托管应用程序的关键性能因素

最近在JVM世界中出现了两个新的GC,它们似乎提供了显著的指标。有一些来源(包括作者)提供了关于这些地面军事系统的基准和技术见解。我们可以了解到,最大STW(停止世界)间隔“被承诺”不再超过10毫秒,并且无论堆大小如何,通常平均振荡在1毫秒以下。还有一些测试表明,新的GCs开销得到了很好的平衡,不会对应用程序吞吐量产生负面影响,同时大大减少了STW暂停(减少了10倍或更多)

另一方面,关于CLR地面军事系统的信息很少。有没有最新的资料来了解CLR GCs(4.8,Core 3.1,.NET 5)与最新的JVM成就的比较? 我可以找到一些讨论CLR GC和G1的老资料。但今天G1无法与ZGC/Shenandoah相匹敌,旧资料也无法显示今天的现实。考虑到没有新的来源,我们可以得出结论,自那时以来CLR GC度量并没有显著改进。但对于2020年的.NET平台来说,这似乎是一个真正的问题,因为平均STW约为20-30毫秒,偶尔会跳到300毫秒以上,与JVM上的平均1毫秒和最大10毫秒(GCs制造商声称和测试似乎证实了这一点)暂停相比,这看起来非常糟糕

我必须说这让我有点担心,因为有很多应用程序GC暂停非常重要。事实上,它们是决定指定技术(例如,NET、JVM、native等)是否适合某项任务或目的的关键因素之一。看起来JVM上的最新GCs为Java和其他JVM语言/技术开辟了新的领域。我们不允许应用程序停止500ms左右的区域,因为GC必须执行其工作,而最大10ms,平均1ms就足够了


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

这是一个大问题,但如果我必须总结一下:

  • shenandoah、zgc等都是低延迟垃圾收集器:它们牺牲吞吐量以确保非常低的暂停时间。它们适用于某些类型的应用程序(基本上,任何具有低延迟约束的应用程序),但不适用于其他应用程序(举一个极端的例子,对于一批您根本不关心延迟并希望最大化吞吐量的应用程序,这使得那些地面军事系统成为一个糟糕的选择)
  • 到目前为止,.NET没有低延迟GC。我听说有一些长期计划要实施一项,但我怀疑至少再过两年我们会看到什么
  • .NETGC有一种与JavaGCS截然不同的方法。Java GCs可以进行非常精细的调优,但代价是非常复杂。NETGC的目标是“只工作”,虽然设置很少,但易于理解和利用。这一点越来越不真实,因为.NETCore添加了一系列配置旋钮,例如用于调整Gen0预算
我们不允许应用程序停止运行的区域 500毫秒左右,因为GC必须完成其工作,而 平均1毫秒就足够了


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

您这里有一些好的观点,我将只讨论一个。在我12年的代码编写过程中,我遇到了另外一位了解java垃圾收集器基本知识的开发人员:它们是可配置的,但更多时候,开发人员会忽略它们。ZGC正在变得更好。JDK 16的初步结果显示,在3 TB堆上,最大暂停时间不到1毫秒。“有问题的GC暂停已成为过去”