引用类型:引用类型存储在堆中。类型实例化的时候,会在堆中开辟一部分空间存储类的实例。类对象的引用还是存储在栈中。
值类型:值类型总是分配在它声明的地方,做为局部变量时,存储在栈上;类对象的字段时,则跟随此类存储在堆中。
https://www.cnblogs.com/zd1994/p/4424329.html
http://www.cnblogs.com/kirinboy/archive/2012/06/12/value-and-reference-in-csharp-1.html
关键字:.method表示方法的意思,.method private hidebysig static void Main(string[] args) cil managed表示的意思就是static void main(string[] args)
.entrypoint标志方法的入口
.maxstack表示分配堆栈大小
.locals init中存放的是当前方法的局部变量,这里面是string类型,它的名称叫hello。Init指令表示对变量应以对应的类型默认值进行初始化,通常情况下变量名可以省略,在代码中将以零基索引来引用
例如:stloc.0表示将Envaluation Stack中的一个栈顶数值保存到局部变量0(Call Stack)中。
先介绍几个关于MSIL内部知识点:
①.Managed Heap:这是动态配置(Dynamic Allocation)的记忆体,由 Garbage Collector(GC)在执行时自动管理,整个 Process 共用一个 Managed Heap,可以理解为引用类型的东西都放在这个Managed Heap中。
②.Call Stack:这是由 .NET CLR 在执行时自动管理的记忆体,每个Thread都有自己的Call Stack堆栈。每调用一次method,就会使得Call Stack上多了一个Record Frame;调用完毕之后,此Record Frame会被丢弃。一般来说,Record Frame内记录着method参数(Parameter)、返回位址(Return Address)、以及局部变量(Local Variable)。.NET CLR都是使用0, 1, 2…编号的方式来识别局部变量。
③.Evaluation Stack:这是由.NET CLR在执行时自动管理的记忆体,每个Thread都有自己专属的Evaluation Stack。压入的到Evaluation Stack的值,当方法调用结束时必须保持这个堆栈的平衡,这里面存放例如局部变量值,以及引用类型的地址。
指令ldc是将参数存储至堆栈Evaluation Stack
指令stloc是将变量存储至堆栈Call Stack
技巧:ld开头就是加载数据到Evaluation Stack中,而st开头就是将Envaluation Stack中的数据保存到Call Stack,Call Stack存放局部变量值。
接下来我们将演示代码的堆栈情况。