还是以下代码:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("WuLin ZhiZun BaoDao Tulong");
A a = new A();
a = null;
GC.Collect();
Console.ReadLine();
}
public virtual void ABC()
{
Console.WriteLine("ABC ");
}
~Program()
{
Console.WriteLine("Kill A Program");
}
}
.
这段C#源码会被编译为IL,构成了四个方法,分别是静态方法Main,虚方法ABC,析构方法Finalize,以及默认构造函数.ctor。
通过WinDbg观察得到
00007FFE0304C770 00007ffe030f4948 NONE CoreCLR_CeShi.Program.Finalize()
00007FFE03040098 00007ffe03010c08 NONE System.Object.ToString()
00007FFE030400A0 00007ffe03010c18 NONE System.Object.Equals(System.Object)
00007FFE030400B8 00007ffe03010c58 NONE System.Object.GetHashCode()
00007FFE0304C768 00007ffe030f4938 NONE CoreCLR_CeShi.Program.ABC()
00007FFE0304C778 00007ffe030f4968 NONE CoreCLR_CeShi.Program..ctor()
00007FFE0304C760 00007ffe030f4920 JIT CoreCLR_CeShi.Program.Main(System.String[])
可以看到Finalize次序为1,Tostring为2,Equals为3,GetHashCode为4,虚方法ABC为5,默认构造.ctor为6
这个排序是怎么排的呢?
其实它是两轮排序:
第一次排序会过滤掉静态方法和非虚方法。那么Main和
.Ctor被排除掉了。虚方法ABC和Finalize(这个析构函数在编译为IL的时候也会被标记为虚方法)则会被处理。注意Finalize因为索引为1的位置已经有了,所以索引为1地方的Finalize会被当前类析构函数的Finalize所取代。
第二轮排序的时候,会首先查找默认构造函数和非默认构造函数,然后排序。最后查找上一轮没有被排序的也就是Main,放到排序次位的最后面。
结果也就是上面windbg展示的结果。索引从1到7.