C#之CLR内存深入分析

作者:shichen2014 时间:2023-01-24 17:18:07 

本文不再对值类型进行讨论,主要讨论一下引用类型。如要看内存值类型的朋友可以看一下前一篇C#之CLR内存原理初探。

C#引用类型具体分析如下:

先来装备两个类:


internal class Employee
{
public static Employee LookUp(string name)
{
 return null;
}

public virtual string GetProgressReport()
{
 return string.Empty;
}
}

internal class Manager : Employee
{
public override string GetProgressReport()
{
 return string.Empty;
}
}

Employee类里有一个虚方法GetProgressReport和一个静态方 * ookUp,Manager类继承了Employee并重写了GetProgressReport.


static void Main(string[] args)
{
Employee e = new Manager();
e = e.LookUp("Tom");
e.GetProgressReport();
}

 我们在Main里面写上这样的代码,再来对照着下图看看栈和堆是怎么运作的。

C#之CLR内存深入分析

 当JIT编译器将这些IL代码转换成本地CPU指令时,会注意到所有的类型:Employee,Manager,String(由于Tom字符串).

1.当运行方法之前,"prologue"代码会为这些对象在内存中开辟空间。

2.Employee e=new Manager();会把e压入栈,然后保存Manager对象地址,我们在初级篇的时候说过,每个对象都有一个同步块索引和类型对象指针,这个指针就是内存的地址。

C#之CLR内存深入分析

3.e=Employee.LookUp("Tom");调用一个静态方法时,CLR会定位与定义静态方法的类型对应的类型对象。然后JIT编译器在类型对象的方法表中查找与被调用的方法对应的记录项,对方法进行JIT编译(如果需要的话),再调用JIT编译的代码。这个时候我们知道LoopUp返回的是Employee对象(这时,我们一开始创建的Manager对象还不确认有没有被清除,因为GC会自动去清理这些托管代码),所以在堆上面开辟一个Employee的内存块并把e的地址改变成Employee对象所在的位置。 

注意:Employee和Manager类型对象都包含了“类型指针对象”成员。这时由于类型对象本质上也是对象。CLR创建类型对象时,必须初始化这些成员。初始化成什么呢?CLR开始在一个进程中运行时,会立即为MSCorLib.dll中定义的System.Type类型创建一个特殊的类型对象。Employee和Manager类型对象都是该类型的”实例“。 因此,它们的类型对象指针成员会初始化成对System.Type类型对象的引用。

顺便说一句Object.GetType返回的就说”类型指针对象“所存储的地址。

C#之CLR内存深入分析

标签:C#,CLR,内存
0
投稿

猜你喜欢

  • Java输入/输出流体系详解

    2023-03-01 06:37:00
  • C#中ref和out的区别浅析

    2021-12-22 23:00:50
  • 探究Java常量本质及三种常量池(小结)

    2023-06-17 10:28:17
  • C#创建压缩文件的实现代码

    2022-07-28 23:55:04
  • 解决Android Studio突然不显示logcat日志的问题

    2021-06-09 01:13:13
  • 一文详解Spring的Enablexxx注解使用实例

    2023-09-03 08:43:18
  • Java源码解析之ClassLoader

    2022-06-14 06:07:47
  • JAVA设计模式----建造者模式详解

    2022-05-18 22:55:52
  • Android Studio多渠道打包的配置方法

    2023-06-15 23:19:48
  • Java泛型定义与用法实例详解

    2023-11-25 11:50:28
  • 实现Android 滑动退出Activity的功能

    2023-04-24 03:00:34
  • 简单了解Java方法的定义和使用实现

    2021-11-07 06:12:53
  • 仅4行代码实现Android快速文件下载

    2022-08-14 08:06:54
  • 举例说明自定义C++异常处理的实例

    2022-10-25 13:45:27
  • 基于C#实现XML文件读取工具类

    2021-10-07 07:42:19
  • Springboot整合knife4j与shiro的操作

    2023-08-25 08:31:42
  • Java通过匿名类来实现回调函数实例总结

    2023-06-26 12:30:42
  • SpringBoot登录拦截配置详解(实测可用)

    2023-04-22 20:52:21
  • Spring在多线程下@Resource注入为null的问题

    2022-09-11 07:41:18
  • Java实现读取文章中重复出现的中文字符串

    2022-04-27 04:29:05
  • asp之家 软件编程 m.aspxhome.com