C# 防止在短时间内进行.NET垃圾收集
我有一个处理大量数据的高性能应用程序。它正在很短的时间内接收、分析和丢弃大量信息。这会导致我目前正在尝试优化的大量对象搅动,但也会导致第二个问题。当垃圾收集启动时,它会在清理过程中导致一些长时间的延迟(我所说的长时间是指10到100毫秒)。99%的时间这是可以接受的,但是对于大约1-2分钟的短暂时间窗口,我需要绝对确保垃圾收集不会导致延迟。我知道这段时间什么时候会提前发生,我只需要一种方法来确保垃圾收集不会在这段时间内发生。该应用程序是用C#编写的,使用.NET4.0框架,如果需要的话,可以同时使用托管和非托管代码 我的问题是,C# 防止在短时间内进行.NET垃圾收集,c#,performance,garbage-collection,C#,Performance,Garbage Collection,我有一个处理大量数据的高性能应用程序。它正在很短的时间内接收、分析和丢弃大量信息。这会导致我目前正在尝试优化的大量对象搅动,但也会导致第二个问题。当垃圾收集启动时,它会在清理过程中导致一些长时间的延迟(我所说的长时间是指10到100毫秒)。99%的时间这是可以接受的,但是对于大约1-2分钟的短暂时间窗口,我需要绝对确保垃圾收集不会导致延迟。我知道这段时间什么时候会提前发生,我只需要一种方法来确保垃圾收集不会在这段时间内发生。该应用程序是用C#编写的,使用.NET4.0框架,如果需要的话,可以同时
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文章,也有帮助:
- (这就是为什么我们调用
)PrepareConstrainedRegions()
GCSettings.LatencyMode=GCLatencyMode.LowLatency
只能在GCSettings.IsServerGC==false
时设置<可以在App.config
中更改代码>IsServerGC:
<runtime>
<gcServer enabled="false" />
</runtime>
.NET 4.6添加了两个新方法:仅此而已。这与每个类上的自定义IDisposable
实现如何帮助解决您的问题有些重叠?这些对象在处理后仍然需要GC'ed,不是吗?IDisposable
与垃圾收集无关。@LukeH-通过IDisposable接口的大量工作,我可以让每个对象检查应用程序是否处于关键时期,并在该时期结束之前阻止最终确定。这种方法需要付出大量的努力,并且有许多可能的缺点,但从理论上讲,它是可以使用的。一旦关键时期结束,将有大量的清理工作从巨大的突然完成的物体中进行。不是特别漂亮。@LukeH使用IDisposable接口,您可以在对象最终确定之前捕获它。此时,您将检查程序中的单例引用,以确定应用程序是否处于关键路径状态。如果是这样的话,请缩短完成时间,并将对象添加到清理队列中,以便以后处理。只要对象在该清理队列中被引用,它就不受GC的约束。关键路径状态完成后,清除队列中的所有对象都将被销毁并最终确定。老实说,我一点也不喜欢这样,我也不确定会不会有很大的副作用。这只是一个想法。如果你不介意的话,可以问几个问题。1.我知道关键事件将发生的一般时间段,但它将由从多播广播接收的数据元素触发。我想防止GC延迟接收该数据。你推荐什么?2.当您进入ConstrainedRegion或切换到LowLatency模式时,是否会影响性能?我一看到特定的数据项就可以这样做,而不会受到条目性能的影响吗?顺便说一句,非常有用的东西-谢谢。对于1,我想说的是,如果一般时间段很短,大约几秒钟,那么您可能可以将GC设置为LowLatency
,直到消息到达。再长一点,我想说你对我的知识无能为力。如果绝对不能有GC延迟,可以尝试在另一个进程中接收广播,然后将其封送到主进程,但这会使事情变得非常复杂。对于2,输入CER我认为在您输入和退出时会带来性能影响,但我从未测量过它,也没有自己设置延迟模式。感谢您提供的新信息。如果我能在这个问题相关的时候把它拿回来,那就太好了。希望它能帮助有同样问题的新人。