如何使.NET垃圾收集频率降低?

时间:2011-02-08 09:20:02

标签: .net garbage-collection

我有一个应用程序可以处理大量的小对象,例如:每秒2000条消息。一条消息大约是100字节,可能更少。该应用程序在负载下运行了6个半小时,在此期间它有264 416 0 th gen集合, 166 699 1 st gen和69 608 2 nd gen。这是每秒11.6,7.3和3个集合。

问题是如何减少垃圾收集的频率?

UPD: 应用程序是一个服务器,它从WCF接收消息,通过几个处理模块将它们保存到数据库中。

我觉得GC应该在一段时间后适应并增加发电量,但事实并非如此。

UPD 2 :正如leppie's answer GC中所建议的那样,服务器模式下的收集确实减少了10倍。而且,正如Richter所描述的那样,频繁的收藏并不是一件坏事。

6 个答案:

答案 0 :(得分:9)

是什么让你觉得这会影响你?特别是,gen-0系列非常非常便宜 - 值得鼓励。

我会更多地看看“”可能会导致其中一些请求将gen-0转移到gen-1;我是否不必要地抓住任何物体,例如通过事件?“。

当然,另一件需要注意的事情是:是否有任何地方可以避免创建不必要的对象,例如:

  • 你是在循环中进行字符串连接而不是StringBuilder吗?
  • 任何可以使用正确长度初始化的中等到大型集合,以避免重新分配?
  • 任何可以重复使用的临时缓冲区?例如,你做了很多在方法中短暂使用byte[]的编码工作,其中byte[]可以作为临时区域传入,还是从池中获取?
  • 可以缓存和重用的任何其他内容 - 例如,在方法内创建的new Regex("some literal"),可以创建为静态字段,并为性能编译
  • 任何可以使用实习的强化字符串解析? (不一定是内置的interner)

答案 1 :(得分:4)

如果在app.config中启用gcServer="true",您将获得大约10倍的GC。但请注意,这不会提高性能,如果它是桌面应用程序,您的应用程序可能会增加延迟。

这是app.config设置:

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

答案 2 :(得分:1)

第0代收藏品的数量是正确的。 Gen#1和#2太高,这些物体的寿命太长。也许你把它们排成队列,他们在那里待了一会儿才能得到处理。否则表示您已接近饱和状态。除了更快地处理它们之外,汇集缓冲区可能有所帮助。

答案 3 :(得分:1)

您是否考虑过使用值类型而不是引用类型?如果“对象”是瞬态的并且仅在处理期间需要,那么它可能是一个很好的选择。值类型(结构)在堆栈上分配,因此不需要集合(如类实例)。

答案 4 :(得分:0)

您的问题不是垃圾收集器,而是您有太多对象。 如果您的进程是串行的,并且您不需要同时在内存中包含所有这些对象,请尝试重用而不是create和destory。 如果性能是你的目标,使用其他类型的结构来存储数据,例如数组,内存流或其他,但不是对象的集合。

答案 5 :(得分:0)

也许您应该考虑使用对象池或flyweights。更多可重复使用的对象通常会减少垃圾并降低GC的使用频率。