prevent .NET垃圾收集的时间短时期 [英] Prevent .NET Garbage collection for short period of time

查看:201
本文介绍了prevent .NET垃圾收集的时间短时期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个处理一个非常大的数据量的高性能应用。据接收,分析和在很短的时间段丢弃大量的信息。这导致目前我正在试图优化对象流失了相当多的,但它也引起第二个问题。当它的垃圾收集踢可能会导致一些长时间的延迟,因为它清除的东西了(长我的意思是10秒到毫秒级的100S)。时间这个99%是可以接受的,但短暂的时间窗口约1-2分钟长,我需要绝对确保垃圾收集不会导致延迟。我知道,当时间的这些时期会发生事先我只需要一种方法来确保垃圾收集不会在此期间发生。该应用程序是使用.NET 4.0框架用C#编写,并使用托管和非托管code如果该事项。

我的问题是;


  1. 是否有可能略微停顿一下,垃圾收集整个程序?

  2. 是否有可能使用System.GC.Collect()我需要免费的垃圾收集和窗口之前强制垃圾回收,如果我做了多久我就会垃圾收集免费的吗?

  3. 请人对最小化整体垃圾收集需要什么样的建议?

请注意 - 这个系统是有很多不同的组件相当复杂。我希望能尽量避免前往一个办法,我必须实现每类程序的自定义IDisposable接口。


解决方案

  GCLatencyMode oldMode = GCSettings.LatencyMode;//确保我们随时可以去catch块,
//所以我们可以设置延迟模式回`oldMode`
RuntimeHelpers prepareConstrainedRegions()。尝试
{
    GCSettings.LatencyMode = GCLatencyMode.LowLatency;    //第2代垃圾收集是现在
    //推迟,除了在极低内存情况
}
最后
{
    //总是设置延迟模式回
    GCSettings.LatencyMode = oldMode;
}

这将允许您禁用GC,你可以尽可能多。它不会做对象的任何大集合,直到


  • 您拨打 GC.Collect的()

  • 您设置 GCSettings.LatencyMode LowLatency 其他东西

  • 操作系统发送一个低内存信号的CLR

这样做时,请小心,因为内存的使用可以爬上非常快,而你在尝试块是。如果GC收集,它这样做是有原因的,你只应该认真考虑这个,如果你的系统上有大量的内存。

在提及问题三,也许你可以尝试像字节数组重用对象,如果你通过文件系统接收信息I / O或网络?如果你解析这些信息输入自定义类,尽量重用那些过,但不知道更多关于你在做什么,我不能透露太多好的建议。

下面是一些MSDN文章,也可以帮助你:

注意: GCSettings.LatencyMode = GCLatencyMode.LowLatency ,才可以设置当 GCSettings.IsServerGC ==假 IsServerGC 可以被改变的App.config

 <&运行GT;
    < gcServer启用=FALSE/>
  < /运行>

I have a high performance application that is handling a very large amount of data. It is receiving, analysing and discarding enormous amounts of information over very short periods of time. This causes a fair amount of object churn that I am currently trying to optimize, but it also causes a secondary problem. When Garbage Collection kicks in it can cause some long delays as it cleans things up (by long I mean 10s to 100s of milliseconds). 99% of the time this is acceptable, but for brief windows of time about 1-2 minutes long I need to be absolutely sure that Garbage Collection does not cause a delay. I know when these periods of time will occur beforehand and I just need a way to make sure that Garbage collection doesn't happen during this period. The application is written in C# using .NET 4.0 Framework and uses both managed and unmanaged code if that matters.

My questions are;

  1. Is it possible to briefly pause Garbage Collection for the entire program?
  2. Is it possible to use System.GC.Collect() to force garbage collection before the window I need free of Garbage Collection and if I do how long will I be Garbage Collection free?
  3. What advice do people have on minimizing the need for Garbage Collection overall?

Note - this system is fairly complex with lots of different components. I am hoping to avoid going to a approach where I have to implement a custom IDisposable interface on every class of the program.

解决方案

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;
}

That will allow you to disable the GC as much as you can. It won't do any large collections of objects until:

  • You call GC.Collect()
  • You set GCSettings.LatencyMode to something other than LowLatency
  • The OS sends a low-memory signal to the CLR

Please be careful when doing this, because memory usage can climb extremely fast while you're in that try block. If the GC is collecting, it's doing it for a reason, and you should only seriously consider this if you have a large amount of memory on your system.

In reference to question three, perhaps you can try reusing objects like byte arrays if you're receiving information through filesystem I/O or a network? If you're parsing that information into custom classes, try reusing those too, but I can't give too much good advice without knowing more about what exactly you're doing.

Here are some MSDN articles that can help too:

Note: GCSettings.LatencyMode = GCLatencyMode.LowLatency can only be set if GCSettings.IsServerGC == false. IsServerGC can be changed in App.config:

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

这篇关于prevent .NET垃圾收集的时间短时期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆