防止.NET垃圾收集很短的时间
我有一个处理大量数据的高性能应用程序。 它在很短的时间内接收,分析和丢弃大量的信息。 这导致我目前正试图优化,但也会导致次要问题的相当数量的对象stream失。 当垃圾收集开始时,可能会导致一些长时间的延迟,因为它会清理一些东西(我的意思是10秒到100毫秒)。 99%的时间是可以接受的,但是对于大约1-2分钟的短时窗口,我需要绝对确保垃圾收集不会造成延迟。 我知道这些时间会在什么时候发生,我只是需要一种方法来确保垃圾收集在这段时间内不会发生。 该应用程序是使用.NET 4.0 Framework在C#中编写的,如果重要,则使用托pipe代码和非托pipe代码。
我的问题是
- 是否有可能暂停垃圾收集整个程序?
- 是否有可能使用System.GC.Collect()在窗口之前强制垃圾收集,我需要免费的垃圾收集,如果我做了多久,我会成为垃圾收集免费?
- 人们对减less垃圾收集整体需求有什么build议?
注 – 这个系统相当复杂,有很多不同的组件。 我希望避免去一个方法,我必须在程序的每个类上实现一个自定义的IDisposable接口。
.NET 4.6增加了两个新的方法: GC.TryStartNoGCRegion
和GC.EndNoGCRegion
。
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
设置为GCSettings.LatencyMode
以外的LowLatency
- 操作系统发送一个低内存信号给CLR
这样做的时候请小心,因为在这个try
块中内存的使用会非常快速地上升。 如果GC正在收集,这是有原因的,如果你的系统有大量的内存,你应该认真考虑这个问题。
在提到问题三时,如果通过文件系统I / O或networking接收信息,也许可以尝试重用字节数组等对象? 如果您将这些信息parsing为自定义类,请尝试重复使用这些信息,但如果不了解更多关于您正在进行的操作的信息,我不能提供太多的好build议。
以下是一些MSDN文章,可以帮助:
- 延迟模式
- 受约束的执行区域 (这就是为什么我们调用
PrepareConstrainedRegions()
)
注意: GCSettings.LatencyMode = GCLatencyMode.LowLatency
只能在GCSettings.IsServerGC == false
设置。 IsServerGC
可以在App.config
更改:
<runtime> <gcServer enabled="false" /> </runtime>