图4-2展示了已加载了CLR的一个Microsoft Windows进程。在这个进程中,可能存在多个线程。一个线程创建时,会分配到一个1MB大小的栈。这个栈的空间用于向方法传递实参,并用于方法内部定义的局部变量。
栈是从高位内存地址向低位地址构建的。在图中,假设线程已经执行了一些代码(栈顶部的阴影区域标示这些代码的数据),现在线程执行的代码开始调用M1方法。
M1方法执行时,[String name="Joe"]在线程栈上分配局部变量name的内存,如图4-3所示。
然后,M1调用M2方法,将局部变量name作为一个实参来传递。这造成name局部变量中的地址被压入栈(参加图4-4)。在M2方法内部,将使用名为s的参数来标识栈位置。另外,调用一个方法时,还会将一个“返回地址”压入栈。被调用的方法在结束之后,应该返回到这个位置。
M2方法开始执行时,线程栈中为局部变量length和tally分配内存,如图4-5所示。然后,M2方法内部的代码开始执行。最终,M2抵达它的return语句,造成CPU的指令指针被设置成栈中的返回地址,而且M2的栈帧会展开,使之看起来类似于图4-3。之后,M1将继续执行在M2调用之后的代码,M1的栈帧将准确反映M1需要的状态。
最终,M1会返回到它的调用者。这同样是通过将CPU的指令指针设置成返回地址来实现的,而且M1的栈帧会展开,使之看起来类似于图4-2。之后,调用了M1的线程会继续执行在M1调用之后的代码,那个方法的栈帧将准确反映它需要的状态。
假定有以下两个类定义:
internal class Employee{ public Int32 GetYearsEmployed(){...} public Virtual String GenProgressReport(){...} public static Lookup(String name){...} } internal sealed class Manager : Employee{ public override String GenProcessReport(){...} }
运行时的相互联系
时间: 2024-10-11 15:52:48