两个类的定义:
{
public Int32 GetYearsEmployed()
{
return 5 ;
}
public virtual String GenProgressReport()
{
return "" ;
}
public static Employee Lookup(String name)
{
return new Manager();
}
}
public class Manager : Employee
{
public override string GenProgressReport()
{
return base .GenProgressReport();
}
}
调用方法:
{
Employee e;
Int32 year;
e = new Manager();
e = Employee.Lookup( " Joe " );
year = e.GetYearsEmployed();
e.GenProgressReport();
}
1.Windows进程启动,并加载CLR到该进程中。托管堆已初始化,并创建一个线程。
2.JIT编译器将M3转换成本地CPU指令,M3内部所引用的所有类型:Employee,Manager,Int32,String(因为“Joe”)都已经创建。假设M3之前已经执行过一些代码,不妨假定 Int32和String类型对象都已经创建,因为这些类型对象实在是太常用了。
类型对象在堆上包括:a.类型对象指针
b.同步块索引
c.静态字段
d.方法表
3.CLR确定所有的类型对象都已创建之后,就允许线程开始执行M3的本地代码。在线程栈中为局部变量分配内存,并初始化所有的局部变量。e为null,year为0
4.M3代码中的 e = new Manager
1).在托管堆中创建Manager类型的一个实例(Manager对象):
a.类型对象指针
b.同步块索引
c.实例字段:
Manager类型定义的所有实例字段
Manager所有基类定义的所有实例字段
2).初始化内部类型对象指针,使它引用与对象对应的类型对象(本例就是Manager类型对象)
3).初始化同步块索引,并将所有实例字段设置为null或0,再调用类型的构造器
4).new 操作符会返回Manager对象的内存地址,该地址保存在变量e中(e在线程栈上)
5. M3代码中的e = Employee.Lookup("Joe")
调用一个静态方法,CLR会定位与定义静态方法的类型对应的类型对象,本例是Employee。然后在类型对象中查找与被调用方法对应的记录项,对该方法进行JIT编译,在调用JIT编译的代码。本例中Lookup方法内部返回的一个Manager对象,所以在堆上构建一个新的Manager对象,用Joe的信息初始化它,然后返回该对象的地址,这个地址保存到局部变量e中。此时,e不再引用第一个Manager对象,由于没有变量引用这个对象,所以垃圾回收机制会自动挥手这个对象占用的内存。
6.调用M3的 year = e.GetYearsEmployed()
调用一个非虚实例方法,JIT编译器会找到与“发出调用的那个变量(e)的类型(Employee)”对应的类型对象(Employee类型对象),如果Employee中没有该方法,就会一直回溯类型层次结构到Object,并在沿途每个类型中查找该方法。找到该方法后,进行JIT编译,再调用JIT编译的代码。假定Employee的GetYearsEmployed返回5,这个整数就保存在局部变量year中,year也在线程栈上。
7.调用M3的e.GenProgressReport()
检查发出掉哦用的变量,然后跟随地址来到发出调用的对象。在本例中,变量e引用的是代表“Joe”的一个Manager对象。然后,检查对象内部的“类型对象指针”成员,这个成员只想对象的实际类型。最后,在类型对象方法表中查找引用被带哦用方法的记录项,对方法进行JIT编译,再调用JIT编译过的代码。本例中会调用Manager的GenProgressReport。
注意,如果Employee的Lookup发现是一个Employee对象而不是Manager对象,最终执行的是Emploee的GenProgressReport。
最后注意,Employee和Manager类型对象都包含“类型对象指针”成员。这是因为类型对象本质上也是对象。CLR创建类型对象时,必须初始化这些成员。CLR开始在一个进程中运行的时候,会立即为MSCorLib.dll中定义的System.Type类型创建一个特殊的类型对象。Employee和Manager类型对象都是该类型的“实例”。因此它们的类型对象指针成员会初始化为System.Type类型对象的引用。
注:本文内容出自《CLR Via C#》,如有什么不妥,请即时联系本人。