Jef*_*ron 21 .net garbage-collection memory-management c#-4.0
我有一个奇怪的情况,我想弄明白.
创世纪:
我在具有16个内核和128GB RAM 的物理机器上运行我的程序.我试图确定为什么它没有使用所有可用的内核,通常它平均使用20-25%的CPU(因此16个中的4-5个内核).当我查看性能计数器时,它们显示垃圾收集时间为60-70%.
作为参考,我使用.NET Framework 4和TPL(Parallel.ForEach)来线程化程序中性能密集的部分.我将线程数限制为核心数.
问题:
我创建了大量的对象,对于垃圾收集器来说有太多的处理效率,因此它在垃圾收集器中花费了大量的时间.
到目前为止简单解决方案:
我正在引入对象池以减少垃圾收集器的压力.我将继续汇集对象以提高性能,已经将一些对象集中在一起,将垃圾收集从60-70%减少到45%的时间,我的程序运行速度提高了40%.
唠叨问题(我希望你能回答我的问题):
运行时我的程序使用最多14GB的可用RAM,而128GB的RAM则相当小.这台机器上没有其他东西在运行(它纯粹是我的测试台),并且有足够的RAM可用.
编辑:
我已经在使用服务器垃圾收集器的选项...我需要知道的是什么是触发gen2集合,而不是服务器垃圾收集器更好(我已经知道).
Jim*_*hel 19
我记得,客户端GC是默认值.我的经验是它在收集之前不会让堆变得非常大.对于我的重型处理应用程序,我使用"服务器"GC.
您在应用程序配置文件中启用了服务器GC:
<?xml version ="1.0"?>
<configuration>
<runtime>
<gcServer enabled="true"/>
</runtime>
</configuration>
Run Code Online (Sandbox Code Playgroud)
这对我来说在性能上有很大的不同.例如,我的一个程序花费了超过80%的时间用于垃圾收集.启用服务器GC将其降低到略高于10%.内存使用量上升是因为GC让它发挥作用,但这对我的大多数应用程序来说都很好.
导致Gen 2集合的另一件事是大对象堆.请参阅CLR Inside Out:大对象堆未覆盖.简而言之,如果超过LOH阈值,它将触发Gen 2集合.如果你要分配很多短寿命的大对象(大约85千字节),这将是一个问题.
从模糊的内存和阅读:http://msdn.microsoft.com/en-us/library/ee787088.aspx,我认为Gen 2 GC的一个触发器可以是第2代段填充.文章指出Server GC使用更大的段,如前所述,这可能对您的性能很重要.
让机器等到几乎没有任何无内存将意味着你在某个阶段得到一个地狱的GC.这可能不太理想.如果您在GC中的时间如此之高,那就表明您正在分配太多的物体,这些物体的存活时间足以超过第0和第1代,并以重复的方式进行.如果应用程序的内存使用量没有随着时间的推移而上升,则表明这些对象实际上是短暂的,但是活得足够长,可以在0和1集合中存活.这是一个糟糕的情况 - 您正在分配一个短期对象,但需要支付完整的第2代收集成本来清理它.
如果是这种情况,您可以采取以下几种不同的指示:
所有这些的组合可能是一个很好的解决方案.你需要很好地理解你分配的对象,他们的生活时间,以及他们实际需要多长时间来实现你的目的.
GC很满意具有较短寿命的临时对象(如可快速通过GC收集),或具有较长寿命的长期/永久性对象.在这两个类别的中间分配大量对象是你痛苦的地方.因此,分配较少的或更改其生命周期以匹配其使用方案.
| 归档时间: |
|
| 查看次数: |
6653 次 |
| 最近记录: |