我有一个应用程序可以处理大量的小对象,例如:每秒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所描述的那样,频繁的收藏并不是一件坏事。
答案 0 :(得分:9)
是什么让你觉得这会影响你?特别是,gen-0系列非常非常便宜 - 值得鼓励。
我会更多地看看“”可能会导致其中一些请求将gen-0转移到gen-1;我是否不必要地抓住任何物体,例如通过事件?“。
当然,另一件需要注意的事情是:是否有任何地方可以避免创建不必要的对象,例如:
StringBuilder
吗?byte[]
的编码工作,其中byte[]
可以作为临时区域传入,还是从池中获取?new Regex("some literal")
,可以创建为静态字段,并为性能编译答案 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的使用频率。