作为对应用程序运行缓慢的解释,有人报告说,收集期间垃圾收集器占用了17%的CPU。对我来说,这个统计数据听起来无关紧要,因为无论如何,17%并不是太令人担忧。此外,它是一个任意的指标,它不会告诉我关于过程记忆的构成。
对我来说更相关的数据是:
我们有多少Gen 2收藏?
告诉我内存转储并让我参加派对并回复你。让我看一下heapstat(来自psscorX的!dumpheap -stat
),syncblocks等。
告诉我在繁重的缓慢时期内的CPU利用率,所以我知道这不是一个I / O限制问题,它要求在设计中引入异步。
自推出可疑操作以来,我们收集了多少垃圾收集?其中有多少是完整收集?
告诉我LOH堆碎片。
显示非托管堆,进程中的可用空间以及托管堆占用的总空间。
对代码进行概要分析,看看花了多少时间。然后调整占用最多时间的操作。
但是一堆垃圾收集所持有的CPU利用率?这对我来说似乎不是一个相关的指标。
所以,我要求确认。
GC使用的CPU指标,尤其是当它只有17%时,是申请中问题的相关指标吗?
GC是否应该通常适用于预期的阈值CPU利用率,以便被视为一个漂亮而健康的应用程序的正常集合?
我们谈论的是在CLR的工作站版本上运行的进程。
答案 0 :(得分:2)
垃圾收集是内存分配的副产品。 如果垃圾收集占用CPU时间的17%,则表明内存分配总体上占很大比例,例如34%。 (当然,如果您的程序受I / O限制,则CPU%不那么重要。)
程序缓慢的一种常见方式(或者说积极的方式,加速程序的常用方法)与可以避免的内存分配有关。 我使用random pausing方法来查明这些机会。
This link探讨了一个例子,其中汇集和重用对象而不是总是分配新对象,这是一个大的加速。 似乎总是需要说的是,程序通常具有多种方式,以便更快地进行,因此性能调整可以分阶段进行。 所以,假设你现在在100秒的时间内花费34分钟内存分配,并假设你可以删除其中的30个。然后时间缩短到70秒,加速度为100/70 = 1.43x。 现在几乎可以肯定其他东西(不一定是内存分配)需要20秒。它是20/100 = 20%,但在解决第一个问题之后它更多;它是20/70 = 29%。 它通过第一次加速成比例地变大。 修复它可以提高70/50 = 1.4x的速度。 如果你遇到多个问题并且一次修复一个问题,那么它们的加速因子会相加,并且会非常引人注目。
答案 1 :(得分:0)
经过一番搜索后,我找到了有关此主题的一些信息here。
在收集过程中检查CPU利用率似乎可以让人们了解是否有太多或太频繁的收集。这可能意味着对象分配太快和/或没有被释放,即生存时间太长(例如太多的类级别对象),因此收集垃圾收集器的时间更长,因为收集的内容不多在每个系列中。
我从文章中重现了相关的片段:
Garbage Collection and Performance - > Issue: CPU Usage During a Garbage Collection Is Too High
垃圾回收期间CPU使用率很高。如果有意义的话 在垃圾收集中花费的处理时间量,数量 收藏太频繁或收藏持续时间太长。一个 托管堆上对象的分配率增加导致 垃圾收集更频繁地发生。减少分配 rate降低了垃圾收集的频率。
您可以使用分配的字节数/秒来监控分配率 表现计数器。有关详细信息,请参阅Performance Counters in the .NET Framework。
然而,这并没有评论17%的CPU利用率是否高,因为它不应该。它提供了一个引导,建议我们查看每秒分配性能指标和% Time
计数器。