CLR运行相互关系(必须要理解的)
假设定义了两个类
我们的Windows进程已经启动,CLR已加载到其中,托管已初始化,已经创建了一个线程。该线程马上要调用M3方法
此时托管堆里没有任何内容,当JIT(just-in-time)编译器将M3的IL代码转换成本地CPU指令时,会注意到M3内部引用的所有这些类型:Employee,Int32,Manager以及Stiring.这个时候CLR要确保定义了这些类型的所有程序集都已经加载打AppDomian中。然后,利用程序集的元数据,CLR提取相关这些类型的信息,并创建一些数据结构在表示类型本身。
此时托管堆里有Manager类型对象和Employee类型对象。这两类型对象包含类型对象指针和同步块索引以及静态字段。
执行"Employee e;Int32 year;"CLR会自动将所有局部变量初始化为null或0;
执行"e=new Manager();" 托管堆会创建Manager类型的实例(也就是Manager对象),它也有一个类型对象和同步块指针以及一个实例字段,该对象还包含容纳Manager类型定义的所有实例数据字段以及任何基类定义的所有实例字段所需要的字节,任何时候托管堆新建一个对象,CLR都会自动初始化内部类型对象指针成员,让它引用对象对应的类型对象(本例为Manager类型对象)。此外 CLR还会首先初始化同步块索引,并将对象的所有实例字段设置为null或0,然后才会调用类型的构造器。new操作返回Manager 对象的内存地址,即在e中
执行"e=Employee.Lookup("jpe");"在调用这个静态方法时,CLR会定位与定义静态方法的类型对应的类型对象,然后 CRL在类型对象的方法表中定位引用了被调用方法的记录项然后对方法进行JIT编译,最后调用IT代码。这里jpe是为经理所以e 的类型是Manager
注意,e不再引用创建第一个Manager对象。事实上,由于没有变量引用这个对象,所以它将是将来进行垃圾收集的主要候选对象。
执行"year=e.GetYearsEmployed();" 在调用一个非虚实例方法时,CLR会找到与出发调用的变量的类型对应的类型对象。(本例为Employee)然后,CLR在类型对象的方法表中找到引用了被调用方法记录项,对方法进行JIT编译,然后调用IT代码。
执行"e.GenProgressReprot(x3);"在调用一个虚实例方法时,CLR会做一些额外的工作。首先,它在用于发出调用的变量中查找,然后跟随地址到发出调用的对象。(本例为Manager)然后,CLR在类型对象的方法表中定位引用了被调用方法的记录项,对方法进行JIT编译,然后调用IT代码
{
Employee e;
Int32 year;
e=new Manager();
e=Employee.Lookup("jpe");
year=e.GetYearEmployed();
e.GenProgressReport(x3);
}
注意若果Employee的Lookup方法发现的jpe只是一个Employee,e的值为employee,那么最后是调用Employee 的GenPorgressReport而不是Manager的GenProress
}
浙公网安备 33010602011771号