短时间内如何阻止.NET垃圾收集?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (14)

我有一个处理大量数据的高性能应用程序。它在很短的时间内接收,分析和丢弃大量信息。这导致我目前正试图优化的相当数量的对象流失,但也会导致次要问题。当垃圾收集开始时,它可能会导致一些长时间的延迟,因为它会清理一些东西(我的意思是10s到100s的毫秒)。99%的时间是可以接受的,但对于大约1-2分钟时间的短时窗口,我需要确保垃圾收集不会造成延迟。我知道这些时间段会事先发生,我只需要一种方法来确保垃圾收集在此期间不会发生。该应用程序使用.NET 4以C#编写。

我的问题是;

  1. 是否可以暂停垃圾收集整个程序?
  2. 是否有可能使用System.GC.Collect()强制垃圾收集之前,我需要免费的垃圾收集窗口,如果我做多久,我会成为垃圾收集免费?
  3. 人们对减少垃圾收集整体需求有什么建议?

注 - 这个系统相当复杂,有很多不同的组件。我希望避免去一个方法,我必须在每个程序类上实现一个自定义的IDisposable接口。

提问于
用户回答回答于
用户回答回答于
GCLatencyMode oldMode = GCSettings.LatencyMode;

// Make sure we can always go to the catch block, 
// so we can set the latency mode back to `oldMode`
RuntimeHelpers.PrepareConstrainedRegions();

try
{
    GCSettings.LatencyMode = GCLatencyMode.LowLatency;

    // Generation 2 garbage collection is now
    // deferred, except in extremely low-memory situations
}
finally
{
    // ALWAYS set the latency mode back
    GCSettings.LatencyMode = oldMode;
}

这将允许尽可能地禁用GC。它不会做任何大型的对象集合,直到:

  • 你调用 GC.Collect()
  • 你设置GCSettings.LatencyMode了其他的东西LowLatency
  • 操作系统发送一个低内存信号给CLR

在做这件事时请小心,因为在您使用该try模块时,内存使用情况会非常快速地上升。如果GC正在收集,这是出于某种原因进行的,并且如果系统上有大量内存,则应该认真考虑这一点。

在提到问题三时,如果你通过文件系统I / O或网络接收信息,也许你可以尝试重用像字节数组这样的对象?如果您将这些信息解析为自定义类,请尝试重复使用这些信息,但如果不了解更多关于您究竟在做什么的内容,我不能提供太多的好建议。

以下是一些可以提供帮助的MSDN文章:

注意: GCSettings.LatencyMode = GCLatencyMode.LowLatency只能设置为GCSettings.IsServerGC == falseIsServerGC可以更改为App.config

  <runtime>
    <gcServer enabled="false" />
  </runtime>

扫码关注云+社区