【问题标题】:How long can I typically keep GC mode set to SustainedLowLatency我通常可以将 GC 模式设置为 SustainedLowLatency 多长时间
【发布时间】:2017-03-11 15:09:08
【问题描述】:

我有一个服务器应用程序,它每秒 50 次从多个传感器接收大量 UDP 数据包(每 20 毫秒新数据包),进行一些分析、存储它们、进行一些调试日志记录和其他“服务器内容”。

问题在于 GC 每隔一段时间执行一次完全阻塞收集,暂停 所有线程 长达 200 毫秒(在某些罕见的百分位数中可能甚至更多)。我对每个数据包滞后几毫秒没有问题(即使每个数据包持续延迟 10 毫秒也不成问题),但长时间暂停真的很烦人。

根据 MSDN,GC 有 SustainedLowLatency mode,根据 MSDN:

启用垃圾回收,以尽量减少长时间的延迟。收集器尝试仅执行第 0 代、第 1 代和并发第 2 代收集。

如果系统处于内存压力之下,仍可能发生完全阻塞收集。

  1. “延长期限”是否仍然意味着我不能简单地将模式设置为SustainedLowLatency 而忘记它?

  2. 有什么方法可以防止完全阻塞集合,至少对于单核?

【问题讨论】:

  • 启用垃圾收集,尝试在较长时间内尽量减少延迟。 意味着中等延迟会很低...偶尔它会很高。 至少对于单个核心这并不意味着什么...如果它被阻塞,那么它将阻塞所有应用程序:-)

标签: c# .net garbage-collection udp low-latency


【解决方案1】:

基本上,此模式将尝试仅使用后台 gen 2 集合,并且仅在系统开始缺少内存时执行完整 GC。阻塞集合之间的延迟完全取决于您的代码:您使用 gen 2 的次数越少,内存碎片就越少,您将持续的时间越长。不幸的是,套接字使用固定缓冲区,这是内存碎片的典型原因。您可以尝试重用缓冲区,但这涉及使用套接字 API 编写棘手的低级代码。

防止完全阻塞集合的唯一方法是使用TryStartNoGCRegion。再说一次,你能坚持多少取决于你分配了多少内存。使用小物件。尽可能使用结构而不是类。当您需要大型数组时,请使用pooling

分析(例如,使用 Jetbrains dotTrace)将帮助您发现和优化分配大量内存的代码路径。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-15
    • 1970-01-01
    • 2014-02-07
    • 2014-08-28
    • 1970-01-01
    相关资源
    最近更新 更多