为什么这段代码的运行会有很大的不同--GC问题
前段时间偶尔在msn上被人问起GC,自己也是不明白,整理了一下不明白的问题。来这里请教。
using System;
using System.Collections.Generic;
using System.Text;
namespace GCDemo
{
class Program
{
static void Main( string[] args )
{
MyClassTemp temp= new MyClassTemp();
//MyClassAdapter temp = new MyClassAdapter();
GCCall();
}
private static void GCCall()
{
Console.ReadLine();
Console.WriteLine( "GC START" );
GC.Collect();
Console.WriteLine( "GC END" );
Console.ReadLine();
}
}
class MyClass : IDisposable
{
#region IDisposable 成员
void IDisposable.Dispose( )
{
throw new Exception( "The method or operation is not implemented." );
}
#endregion
}
class MyClassTemp
{
public MyClassTemp( )
{
Console.WriteLine( "MyClassTemp is Creating" );
}
~MyClassTemp( )
{
Console.WriteLine( "MyClassTemp is Destroying" );
}
}
class MyClassAdapter
{
public MyClassAdapter( )
{
MyClassTemp temp = new MyClassTemp();
}
}
}
-----------------------------------------------------------------
如果把main函数中的代码修改如下 那么得到的结果将会是不同的
//MyClassTemp temp= new MyClassTemp();
MyClassAdapter temp = new MyClassAdapter();
JIT编译main函数,个人感觉好像是把Main函数的所有引用(这里专指引用到heap上的对象)放到root中 MyClassTemp temp= new MyClassTemp(); 这个temp也被放入。那么后来在main函数中调用GC的时候,temp的引用仍然在root中,所以temp并不被GC,而关闭这个控制台程序的时候,temp被GC掉。
如果使用这段代码 MyClassAdapter temp = new MyClassAdapter(); 这个时候main中调用了子函数,此子函数调用结束之后(子函数栈和堆退出了) 这个时候temp这个引用应该是可以从root上移除了,GC的时候,temp被GC.
关乎GC,说得比较清楚地只有jeffrey richer的《Applied Microsoft .Net Framerok Programming》,没有别的书作对照和参考,我也不能很好的理解,如果理解的有错误的地方,望个位路过的留个记号,多多指教。
--------------------------------------------------------------------------------------
http://bluemountain-1980.spaces.live.com/
当我写完这个blog的时候 突然发现这个程序在debug和release状态下的运行结果好像也是不一样的
下面是 李建忠 翻译的《net框架程序设计》中的话,摘抄下来,感觉自己有些糊涂,各位高人给指点一下
P445 当JIT编译器编译一个方法的IL代码时,除了产生本地CPU代码外,JIT还会创建一个内部表。从逻辑上讲,该表的每一个条目都标识者一个方法的本地CPU指令的字节偏移范围,以及该范围中一组包含根的内存地址(或者CPU寄存器)
P446 但是,当应用程序运行在一个调试器中~~~~~~~~~`