W3WP流程中的垃圾收集

时间:2015-08-06 08:41:44

标签: .net debugging iis memory garbage-collection

调试性能问题,其中一台服务器使用的CPU比预期的多,我目前专注于GC,因为GC中的%时间似乎在30左右,我发现它太高了。

此外,我注意到一种模式,CPU使用率逐渐上升,直到每晚午夜游泳池回收。 LOH大小也在不断上升(我怀疑它是因为我们缓存了用户信息),这让我认为不断增长的LOH是CPU的原因,并且GC的百分比正在逐渐增加,直到回收。我也注意到了很多gen2系列。

GC gens

看看这张图,我发现了两件事:

1)GC的模式是否正常?我认为第二代的收集次数要少得多。

2)17:40发生了什么?服务器有两个正在运行的应用程序池(一个只是一个虚拟网站,一个正在完成所有工作),对我而言,它看起来像是在17:40切换位置,没有回收或似乎发生了任何事情。

GC和分配B /秒的时间跟随一个奇怪但上升的模式:

% Time in GC and alloc

1 个答案:

答案 0 :(得分:0)

我不确定17:40发生了什么。

但是,这种模式对于GC来说是正常的。收集Gen2的次数将减少很多次,收集的Gen0将超过Gen1,收集的Gen1将超过Gen.2。

只是介绍GC的工作原理。

对于托管对象,有三个小对象堆(SOH)和一个大对象堆(LOH)。

大对象堆(LOH)

大于85KB的物体将立即进入LOH。如果您有太多大型物体,则存在一些风险。这是一个不同的讨论,有关详细信息,请查看The Dangers of the Large Object Heap

小对象堆(SOH):Gen0,Gen1,Gen2

垃圾收集器使用一种聪明的算法仅在需要时执行垃圾收集器。完全垃圾收集过程是一项昂贵的操作,不应该经常发生。因此,它已将其SOH分为三个部分,因为您已经注意到每个Gen都有指定的内存量。

每个小对象(<85KB)最初都会转到Gen0。当Gen0已满时,垃圾收集仅对Gen0执行。它检查Gen0中的所有实例并清除/释放任何不必要的对象(未引用的,超出范围或处置的对象)使用的内存。然后它将所有必需的(已使用的)实例复制到Gen1。

即使您执行以下操作,上述过程实际上也会发生:(不需要手动调用)

// Perform a collection of generation 0 only.
GC.Collect(0);

通过这种方式,垃圾收集器首先清除为短期实例分配的内存(不可变的字符串,方法中的变量或较小的范围)。

当GC在一个阶段继续执行此操作时,Gen1溢出。然后它对Gen1执行相同的操作。它清除Gen1中所有不必要的内存,并将所有必需的内存复制到Gen2。

当您在下面手动执行(不需要手动调用)

时,会发生上述过程
// Perform a collection of all generations up to and including 1.
GC.Collect(1);

当GC在一个阶段继续执行此操作时,如果Gen2溢出,它会尝试清除Gen2。

即使您在下面手动执行(不需要手动执行)

,也会发生上述过程
// Perform a collection of all generations up to and including 2.
GC.Collect(2);

如果需要从Gen1复制到Gen2的内存量大于Gen2中可用的内存量,GC会抛出内存不足。