C#内存分配

博文带着3个疑问学习:(整理的有错误,请大家帮我改正)

CLR它负责资源管理(内存分配和垃圾收集等),并保证应用和底层操作系统之间必要的分离

问题1CLR(Common Language Runtime 公共语言运行时)管理内存的三块区域是什么?

问题2:哪些操作会 创建对象和分配内存?

问题3:内存的分配机制?

 

  1. CLR管理内存的三块区域
    注:内存——堆栈   堆(托管堆)

 

线程的堆栈:用于分配值类型的实例-有操作系统管理分配释放内存。
GC堆(托管堆):用于分配引用类型的实例对象内存小于8500 byte的。当有内存分配时,垃圾回收器"可能"会对GC堆进行压缩。
LOH堆(Large Object Heap):用于分配引用类型的大对象实例(大于8500byte,不会被垃圾回收器压缩,而且只在GC堆完全被回收时回收。

 

  1. 哪些操作会 创建对象和分配内存?
    IL指令:.net中间语言
    newobj:引用类型对象创建
    ldstr:string类型对象创建
    newarr:数组对象创建
    box:值类型转换引用类型,值类型字段拷贝到托管堆上发生 内存分配

 

3.内存的分配机制
3.1 堆栈的内存分配机制
对于值类型:当作为类的值类型成员时,这个时候值类型将被分配在托管堆(堆)上。如:

class Car
{
    int carYear;
    string carName;
}

 

即:Car oneCar=new Car();  这个Car类的引用变量将被分配在线程堆栈上,而这个对象的成员,如:carYear,carName将被分配在堆上。

 

对于堆栈的变量来说,是由操作系统来分配和释放内存的,操作系统维护着一个堆栈指针来指向一个自由空间(未被分配的内存的开始位)。堆栈的分配是从高位——>低位,而释放是从低位——>高位,如:

 

static void Main()
{
    int i=1;
    char a='A';

}

 

分析:
分配
第一步:C#程序从Main函数开始,每个线程堆栈都有一个初始化地址,比如这个程序的初始化地址是100;
第二步:int类型占有4字节,那么开始堆栈指针是在100这个位置,然后分配4字节给值为1的Int类型(100-97)保存,然后堆栈指针指向96.
第三步:char类型占有2字节,那么堆栈指针由96指向94。
第三步:当运行到右括号的时候,将会释放内存
释放
第四步:释放的步骤是分配的反方向,堆栈指针逐步向上移动。

注:上面的方式更可以说是“局部变量的分配机制”,因为这些值类型变量随着方法的结束而结束,效率高,但是内存容量小。

3.2 堆(托管堆)的内存分配机制
对于引用类型:引用类型的变量的内存是分配在堆栈上的,而引用类型的对象实例的内存是分配在托管堆上的。
对于托管堆里有2个重要的区域:GC堆和加载堆(Loader Heap)

 class Program
    {
        static void Main(string[] args)
        {
            B b =unll;
       b = new B(); b.fild1
= 11; A a = b; a.fild1 = 12; Console.WriteLine("B类型b对象的值为:{0}",b.fild1); Console.WriteLine("A类型a对象的值为:{0}", a.fild1); Console.ReadKey(); } } public class A { public int fild1; } public class B:A { public int fild2; }

回归到我们上一个博客讲解的内容:

  分配
    第一步:Main函数开始,声明一个B类型变量,这只是一个引用,或者说是一个指针,它是存储在堆栈上的,占有4个字节。这个时候,没有指向对象,初始化为NULL。

     第二步:new对象,这个过程很复杂,因为IL(中间代码)代码为newobj,这个过程会一直向上查找其所有父类,直到Object类型,并且这个过程会计算类型和所有继承关系类型的字段,并且返回一个总的占有字节数。

    第三步:分配内存对于堆栈是 先进后出,向低位扩展 ,分配内存是由上-下,释放内存是由下-上。

      对于堆是 先进先出,向高位扩展。分配内存是由下-上,由GC回收器回收内存。

      对于引用类型,父类在前子类在后,当发现内存不足时,会启动GC回收器,回收垃圾对象占用的内存。

    第四步:调用构造函数,进行初始化,完成创建对象过程

   注意:对于b对象的回收不是出了大括号就回收了对象而是等到GC回收器回收的对象

  在这里就很好解释为什么我们输出的a对象和b对象的值都为12.在我们的转换的过程并没有在堆中开辟新的内存空间。一直都是用的可以说是a对象的指针去改变堆中对象的值。

 

 

转载于:https://www.cnblogs.com/-alvin/p/9044290.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这本书是什么? * 这本电子书严格来说是我复习C#基础知识来的,我从09年初开始使用asp.net进行b/s开发,之前一直使用asp。在实际开发中深感C#的强大,也深深感到自身基础知识的欠缺,因此重新从头开始学习C#,在学习的过程中最主要是借助Illustrator C# 2008(译名:插图详解C#2008或C#图解教程)这本书,(准确讲,这本电子书可以说是我对Illustrator C# 2008的读书笔记)同时查阅了msdn及许多相关的资料 ,前后近两个月;但本系列尚未完成,目前还有多线程及涉及C# 3.0中的新知识没有完成。 * 这本书有什么? * 本电子书一共21节,主要包含本人实际项目中自我感到难点的东西,如委托、事件、泛型等,进行了个人的一些总结的归纳,最后附一个我做的WinForm程序。 * 这本书适合哪些人? * 这本书内容其实很少,你可以很快就可看完;内容也只是十分简陋,主要是我本人在实现应用的体会的难点问题的总结。再加上我本人技术水平十分有限,因此我要提前声明:由于内容简略,不适合新手,以免误人子弟;内容浅显,更不适合老鸟。我本人也是抱着交流学习的目的将它发布的,欢迎大家针对本书内容的问题进行交流探讨。 * 最后,极力向大家推荐Illustrator C# 2008,不要被它的名字迷惑,认为它只是一本入门级的读物;作者是技术专家,对C#有极其深刻的见解;语言十分流畅,书中的插图十分形象易懂,从头到尾内容循序渐进,层层递进,尤其对内存分配有着详尽的描述。无论是新手还是老手,绝对值得一读。中文版翻译也还可以,如果英文好的话建议直接阅读英文版。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值