[url=http://d.hatena.ne.jp/NyaRuRu/]NyaRuRuさん的blog[/url]真是一个宝库,有许多有启发性的日记。刚才读到这么一篇:[url=http://d.hatena.ne.jp/NyaRuRu/20060626/p4]this の寿命[/url],虽然是06年的老文,却还是让我惊讶了一番。
文中提到,“this”在实际运行中并不一定在其作用域内都存活;在作用域结束前,它有可能就已经被回收(delete this)了。文中举了这样一个例子(稍微修改过):
testGC.cs:
运行的结果是:
[quote]Get Handle from OS : 123456
Finalize; Release Handle
Use Handle : 123456[/quote]
从trace结果可以看到,Test的析构器在Test.Foo()还在运行中就执行了。这与一般认识似乎相差甚远:Main()里对Test.Foo()的调用尚未完成,也就是说应该还有对这个对象的引用,所以这个Test对象应该暂时还无法被析构才对。
事实上,受到JIT的内联优化等影响,程序运行的时候还有没有对某个对象的引用,与源码中不一定总是对应的;极端情况下,在一个对象的构造器执行过程中,这个对象就可能已经被析构了。在[url=http://blogs.msdn.com/ricom/archive/2004/05/19/135332.aspx#139495]这帖[/url]有一串有趣的讨论。
Chris Brumme也写过一篇关于GC.KeepAlive()的帖子:[url=http://blogs.msdn.com/b/cbrumme/archive/2003/04/19/51365.aspx]Lifetime, GC.KeepAlive, handle recycling[/url]
文中提到,“this”在实际运行中并不一定在其作用域内都存活;在作用域结束前,它有可能就已经被回收(delete this)了。文中举了这样一个例子(稍微修改过):
testGC.cs:
// compile this file with the following command:
// csc /o /d:TRACE testGC.cs
using System;
using System.Threading;
using System.Diagnostics;
class Test {
IntPtr _myHandle = IntPtr.Zero;
~Test( ) {
Trace.WriteLine( "Finalize; Release Handle" );
}
public void Foo( ) {
Trace.WriteLine( "Get Handle from OS : 123456" );
_myHandle = ( IntPtr ) 123456;
Bar( _myHandle );
}
public void Bar( IntPtr handle ) {
GC.Collect( );
Thread.Sleep( 1000 );
Trace.WriteLine( "Use Handle : " + handle.ToString( ) );
}
}
static class Program {
static void Main( string[ ] args ) {
Trace.Listeners.Add( new ConsoleTraceListener( ) );
new Test( ).Foo( );
}
}
运行的结果是:
[quote]Get Handle from OS : 123456
Finalize; Release Handle
Use Handle : 123456[/quote]
从trace结果可以看到,Test的析构器在Test.Foo()还在运行中就执行了。这与一般认识似乎相差甚远:Main()里对Test.Foo()的调用尚未完成,也就是说应该还有对这个对象的引用,所以这个Test对象应该暂时还无法被析构才对。
事实上,受到JIT的内联优化等影响,程序运行的时候还有没有对某个对象的引用,与源码中不一定总是对应的;极端情况下,在一个对象的构造器执行过程中,这个对象就可能已经被析构了。在[url=http://blogs.msdn.com/ricom/archive/2004/05/19/135332.aspx#139495]这帖[/url]有一串有趣的讨论。
Chris Brumme也写过一篇关于GC.KeepAlive()的帖子:[url=http://blogs.msdn.com/b/cbrumme/archive/2003/04/19/51365.aspx]Lifetime, GC.KeepAlive, handle recycling[/url]