当我要求dotMemory强制进行垃圾收集时,究竟发生了什么

时间:2017-02-03 11:03:41

标签: c# .net garbage-collection

我使用dotMemory来分析我的应用程序,我注意到以下行为:在我的代码中有一些点,我通过使用

手动执行垃圾收集
GC.Collect();
GC.WaitForPendingFinalizers();

在dotMemory中我看到内存实际上是在这些点中被释放但是如果之后我点击“强制GC”#39;收集甚至更多的garabage。他们这样做的方式是什么,为什么我的代码没有收集内存,是否可以实现相同级别的收集?

我附上截图,你可以看到第2代几乎减半了dotMemory enter image description here

我还试图进行多次收集,即

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();

即使它似乎回收了更多的内存,它也永远不会接近dotMemory的表现

1 个答案:

答案 0 :(得分:2)

来自JetBrain's Forum

“强制GC”按钮从本机代码调用GC。

当您从代码中调用GC.Collect()方法时,它将执行以下步骤:

释放可以立即释放的内存 查找具有Finalize方法的对象并将其放入队列 GC.Collect()仅释放托管对象。此外,CLR根据情况采用了几种不同的GC策略,以最大程度地减少造成GC的延迟,我们不会对此造成影响。 如果这些对象没有Finalize方法或该方法实现不正确,则永远不会释放托管对象使用的本机内存。

我们建议您使用GC.Collect调用WaitForPendingFinalizers方法并将其重复几次:

for (int i = 0; i < 4; i++)
{
    GC.Collect(2, GCCollectionMode.Forced, true);
    GC.WaitForPendingFinalizers();
}

它可以显示更好的结果,但我们不能保证此代码将导致与从本机代码调用的Full GC相同的结果。

GC.Collect方法:https://msdn.microsoft.com/en-us/library/hh138633(v=vs.110).aspx