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

标签 c# .net garbage-collection jvm clr

近年来,C#(在 .NET 世界中排名第一)中添加了许多功能以减少 GC 压力。无可争辩的是,所有这些功能都使我们能够构建更好、更高效的应用程序。但无论语言和 VM(CLR、JVM)特性如何随着时间的推移而添加,高性能和非阻塞 GC 是托管应用程序的关键性能因素。
最近在 JVM 世界中出现了两个新的 GC,它们似乎提供了非凡的指标。有一些来源(包括作者)提供了关于这些 GC 的基准和技术见解。我们可以了解到,“ promise ”的最大 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、 native 等)是否应被视为对某项任务或目的可行的关键因素之一。看起来 JVM 上的最新 GC 为 Java 和其他 JVM 语言/技术开辟了新的领域。我们不允许应用程序停止 500 毫秒左右的区域,因为 GC 必须完成它的工作,而大约 10 毫秒的最大值和大约 1 毫秒的平均值就足够了。
今天的真相是什么? CLR GC 与最新的 JVM GC 相比如何?是否有关于 CLR 上的 STW 暂停的任何保证(看起来 JVM 正在朝那个方向发展)?

最佳答案

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

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

  • Areas where we do not allow possibility that application will stop for 500ms or so because GC has to do its work whereas ~10ms maximum with ~1ms average is good enough.


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

    关于c# - CLR GC 与 JVM 上最新的 ZGC 和 Shenandoah GC 相比如何?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64252590/

    相关文章:

    c# - C# 中的文件记录器

    c# - CS1998如何实现不警告的同步任务返回方法?

    c# - 检索进程描述信息

    c# - 对象的惯用 C# 仅通过注册到事件进行交互

    c# - Protobuf-net:试图读取流的末尾

    c# - ASP 标识角色不存在错误

    c# - 量化垃圾收集与显式内存管理的性能

    java - 在游戏关闭时处理 libGDX 资源?

    c# - LINQ 分组到多个组

    c# - 使用 .First() 和 .Count() 破坏了 IEnumerable?