• 类型,对象,线程栈,托管堆在运行时的关系,以及clr如何调用静态方法,实例方法,和虚方法(第二次修改)


    1、线程栈

    window的一个进程加载clr。该进程可能含有多个线程,线程创建的时候会分配1MB的栈空间。

    如图:

     void Method()

    {

      string name="zhangsan";  //name 被放入栈里面

           Method2(name);  //1参数变量s 被压入栈,s引用name的地址    2.返回地址被压入栈,方法执行完(method2的 return)指针指向此返回地址

           return;    

    }

    void Method2(string s)

    {

      int32 length=s.Length;

           int32 tally;

      return;    //methed2执行完后,指针指向线程栈的返回地址,method2的栈帧展开

    }

    2.运行时关系

    现有如下2个类型

    internal class Employee

    {

      public int32 M1(){.....};

      public virtual string M2(){.....};

      public static Employee M3(string name){.....};

    }

    internal sealed class Manager:Employee

    {

      public override string M2(){.....};

    }

    准备:window进程已经开启,clr已经加载到进程里面,托管堆已经初始化,线程栈也已经被创建(连同它的1MB的栈空间)

    void M4()

    {

      Employee e;

      int32 age;

      e=new Manager();

      e=Employee.M3("zhangsan");

      age=e.M1();

      e.M2();

    }

    a.首先介绍下new 关键字的执行的时候会执行什么

    1.clr计算出类型的所有实例字段的字节和所有基类型的实例字段的字节长度,创建类型对象指针和同步块索引(也计算在字节长度内)

    2.在托管堆上分配第一步长度的空间

    3.初始化类型对象指针(指向类型对象)和同步块索引

    4.调用类型的实例构造器。

     b.运行关系图

     c.详细解释

           1.M4运行的时候 先在线程栈 压入e和age两个局部变量

      2.e=new Manager();会在托管推上分配Manager和所有基类的实例字段字节大小,初始化类型对象指针,指向Manager类型对象。

      3 调用静态方法,Employee.M3("zhangsan");直接找到M3j静态方法的定义类型Employee,然后去类型对象的方法列表中找到这个方法( 第一个对象将被垃圾回收器回收),

        然后JIT进行编译,然后执行。

      4.调用非虚方法,e.M1(); 找到变量e的声名类型(Employee),在方法列表中找到对应的方法,编译执行(如果没有就向上回溯直到System.Object,能够会所查找方法是因为在派生类中有指向基类的引用)

      5.调用虚方法,e.M2()找到e对象,利用其指针找到e 的实例对象类型(Manager对象),在利用实例对象的类型对象指针找到对象的实际的类型对象(Manager),调用Manager类型对象方法列表中的M2 而不是Employee中的。

  • 相关阅读:
    oracle 下创建数据实例
    MyEclipse7.02注册码
    liferay 5.1学习遇到的错误
    详解struts2中struts.properties
    cas部署到linux登陆也出现异常
    java 字符串和输入流互转
    ASP 的Base64加密 与ASP MD5加密
    Struts2直接下载从数据中的blob类型字段( Struts2.0下载文件流)
    java 汉字转拼音
    java调shell,可以输入参数
  • 原文地址:https://www.cnblogs.com/wupo/p/9488766.html
Copyright © 2020-2023  润新知