【C#基础】初探.Net内存分配原理

基本概念

CLR:公共语言运行时,类似Java的jvm,是直接建立在OS上的虚拟环境,主要任务是管理代码运行。CLR现在支持几十种现代的编程语言为它编写代码,然后以一种中间语言(Intermediate Langeoage,IL)代码的形成被执行。

.Net CLR非常详细讲解了clr原理东西。

线程堆栈:用于分配值类型实例。堆栈主要由操作系统管理,而不受垃圾收集器的控制,当值类型实例所在方法结束时,其存储单位自动释放。执行效率高,但存储容量有限。

GC堆:用于分配小对象实例。如果引用类型对象的实例大小小于85000字节,实例将被分配在GC堆上,当有内存分配或者回收时,垃圾收集器可能会对GC堆进行压缩。

LOH堆:用于分配大对象实例。如果引用类型对象的实例大小不小于85000字节时,该实例将被分配到LOH堆上,而LOH堆不会被压缩,而且只在完全GC回收时被回收。

TypeHandle(类型句柄):指向对应实例的方法表,每个对象创建时都包含该附加成员,并且占用4个字节的内存空间。我们知道,每个类型都对应于一个方法表,方法表创建于编译时,主要包含了类型的特征信息、实现的接口数目、方法表的slot数目等。

NextObjPtr:由托管堆维护的一个指针,用于标识下一个新建对象分配时在托管堆中所处的位置。CLR初始化时,NextObjPtr位于托管堆的基地址

分配原则

.Net中的资源分为托管资源(受clr管理)和非托管资源(不受clr管理),取决于变量的数据类型,托管资源被存放在托管堆和堆栈中。

托管资源数据类型分为值类型和引用类型,关于两者的联系,之前的博客 【傻傻分不清楚】C#值类型、引用类型 做了比较。

值类型实例

对于值类型的实例,CLR在运行时有两种分配方式:(1) 如果该值类型的实例作为类型中的方法(Method)中的局部变量,则该实例被创建在线程栈上;(2) 如果该值类型的实例作为类型的成员,则该实例作为引用类型(引用类型在GC堆或者LOH上创建)的实例的一部分,被创建在GC堆上

    public class Test1  
    {  
        private int i;  
    //上面(2)中的情况,生成Test的实例的同时,int类型的实例i被创建在GC堆上  
        public Test1()  
        {  
            byte b =0;  
    //(1)中的情况,byte类型的实例b被创建在执行这段代码的线程栈上  
        }  
    }  

引用类型实例

对于引用类型的实例,CLR在运行时也有两种分配方式:(1) 如果该引用类型的实例的Size<85000Byte,则该实例被创建在GC(Garbage Collection)堆(当CLR在分配和回收对象时,GC可能会对GC堆进行压缩);(2) 如果该引用类型的实例的Size>=85000byte,则该实例被创建在LOH(Large Object Heap)上(LOH不会被压缩)。

    public class Test2  
    {  
        private int[] intArr;  
        public Test2()  
        {  
            private Object o = new Object();  
    //引用o存在线程栈上,它指向GC堆上的Object实例  
            intArr = new int[21250];  
    //符合(2)中的Size条件,int数组的实例被创建在LOH上  
        }  
    }  

有大神写的博客,.NET下的内存分配机制做了非常详细的分析!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值