我怎样才能重现此.NET垃圾收集情况
这里是一个代码执行意想不到的点可能会出现约GC一大篇:我怎样才能重现此.NET垃圾收集情况
终身,GC.KeepAlive,拉手回收 - 由cbrumme http://blogs.msdn.com/b/cbrumme/archive/2003/04/19/51365.aspx?wa=wsignin1.0
我的问题是如何在文章中提到的点再现强制GC?我尝试在OperateOnHandle()的开头放置GC.Collect(),并为类C定义了析构函数,但似乎不起作用。析构函数总是在程序结束时被调用。
@Jon,谢谢你建议我用尽调试器。现在我能够使用调试器优化的Release版本来重现文章中描述的问题。它证明了自从.NET v1以来,GC的行为不会改变。
码我用:
class C1
{
// Some unmanaged resource handle
IntPtr _handle = IntPtr.Zero;
static void OperateOnHandle(IntPtr h)
{
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("After GC.Collect() call");
// Use the IntPtr here. Oops, invalid operation
}
public void m()
{
OperateOnHandle(_handle);
}
~C1()
{
// Release and destroy IntPtr here
Console.WriteLine("In destructor");
}
}
class Program
{
static void Main(string[] args)
{
C1 aC = new C1();
aC.m();
}
}
输出:
在析构函数 GC.Collect的()调用之后
记住,这篇文章是从2003年,这是使用CLR V1 。我们现在使用CLR v4(虽然没有v3),所以我并不完全感到惊讶,你没有看到完全相同的行为。
目前我甚至无法进入链接页面,而且您还没有包含页面描述内容的描述。在实例方法结束之前是否有可能收集垃圾对象?
如果是这样,那么您可能有问题的最明显的原因是如果您使用调试器。垃圾回收器是,当你在没有附加调试器的情况下运行时,其他更具攻击性。
下面是一个简短而完整的程序在调试器不运行时,这表明该问题:
using System;
class ClassWithFinalizer
{
private int value;
public ClassWithFinalizer(int value)
{
this.value = value;
}
~ClassWithFinalizer()
{
Console.WriteLine("Finalizer running!");
}
public void ShowValue()
{
Console.WriteLine(value);
Console.WriteLine("Calling GC.Collect()");
GC.Collect();
Console.WriteLine("Calling GC.WaitForPendingFinalizers()");
GC.WaitForPendingFinalizers();
Console.WriteLine("End of method");
}
}
class Test
{
static void Main()
{
var x = new ClassWithFinalizer(10);
x.ShowValue();
}
}
汇编(优化,没有调试符号,只是为了给它的最好机会!):
csc /o+ /debug- Test.cs
现在运行,具有输出:
c:\users\Jon\Test>test
10
Calling GC.Collect()
Calling GC.WaitForPendingFinalizers()
Finalizer running!
End of method
注意如何终结运行是该方法已完成。
经测试与.NET 4和.NET 3.5。
在Main()的末尾放置Console.ReadLine()来重现OP的问题。 – 2010-09-19 12:15:42
@Hans:Nope ...我刚刚把Console.ReadLine()和结束,它的行为方式是一样的。在方法结束之前调用终结器。 – 2010-09-19 12:32:24
谢谢你的例子。 – Sheen 2010-09-19 22:45:39
这是一篇旧文章(2003),所以很可能后一版本的.Net Framework会导致不同的行为。 – 2010-09-19 11:43:53
这篇文章真的是关于SafeHandle的。他还不能透露。 – 2010-09-19 12:16:22
@Hans,是的,你是对的。这完全关乎SafeHandler。 – Sheen 2010-09-19 22:45:11