在Perfmon中看到“%GC时间”的原因

时间:2009-07-15 15:12:53

标签: c# .net memory memory-management

在Perf Mon中监控我们的应用程序时,我注意到GC的时间百分比在20-60%之间,而我们的应用程序执行长时间运行的过程(在30秒到1.5分钟之间变化)。这对我来说似乎有些过分。这提出了两个重要问题。

  1. 我认为这太过分吗?
  2. 路线我可以弄清楚GC为什么会这么多?

3 个答案:

答案 0 :(得分:12)

是的,这确实听起来过分了。减少GC的数量可能是减少应用程序运行时间的最佳步骤(如果这是您的目标)。

GC中的“%时间”通常是通过分配然后丢弃数千或数百万个对象引起的。找出正在发生的事情的好方法是使用内存分析器工具。

Microsoft提供免费CLR Profiler。这将显示每个分配,但会使您的应用运行速度慢10-60倍。您可能需要在较少的输入数据上运行它,以便它可以在合理的时间内完成分析。

一个伟大的商业工具是SciTech的.NET Memory Profiler。这会减少运行时开销,并且可以免费试用。通过在进程运行时获取多个快照,您可以找出经常分配(然后销毁)的对象类型。

一旦确定了分配的来源,就需要检查代码并弄清楚如何减少这些分配。虽然没有一个适合所有人的答案,但我过去遇到过的一些事情包括:

  • String.Split可以创建数百个小的短期字符串。如果你正在进行大量的字符串操作,它可以通过逐个字符地处理它来帮助处理字符串。
  • 创建数千个小类(例如,大小不超过24个字节)的数组或列表可能很昂贵;如果这些类可以被视为值类型,它可以(有时)大大改进将它们更改为结构的东西。
  • 创建数千个小数组会大量增加内存使用量(因为每个数组都有少量开销);有时这些可以用一个大数组代替,并索引到它的一个子部分。
  • 有很多可终结的物品(特别是如果它们没有被处理掉的话)会给垃圾收集器带来很大的压力;确保您正确处理所有IDisposable对象,并注意您自己的类型应该(几乎)never have finalizers
  • Microsoft有一篇文章Garbage Collection Guidelines用于提高性能。

答案 1 :(得分:2)

我是否认为这太过分了?

是的,你是对的

路线我可以弄清楚为什么GC会发生这么多?

1.-请查看 PerfView

  

PerfView是一种性能分析工具,可帮助隔离CPU和   与记忆相关的性能问题。

另请参阅:Improving Managed Code Performance

2.-查看是否在代码或第三方库中的任何位置调用GC.Collect或GC.WaitForPendingFinalizers。后者会导致高CPU利用率。

答案 2 :(得分:1)

另一个原因可能是许多gen-1或gen-2集合,每个集合花费的时间更长,并且是由于长时间挂在物体上造成的。

当有错误的对象挂在实际的页面对象上时,我发现这种情况发生在Web应用程序中 - 只要其他对象引用它们,就会强制页面生效。

断开对象和页面之间的链接(在本例中)会导致GC降至非常低的值。我们的网站现在有100多次点击/秒,GC时间通常为1%或更低。