在C#的入门中,值类型和引用类型是一个必须搞清楚的问题,这个问题我思索了很久,一直没有确切的概念,刚才看了<<C#高级编程(第3版)>>后似乎有了一些个人理解的概念.

  在Windows内存中存在这一个叫做虚拟内存的内存区域,是为了提供缓存速度而将硬盘空间划分给内存空间的一部分内存,由于不是实际的内存,只是为了方便缓存数据的,因此叫做虚拟内存,而我们的主角---堆和堆栈就在这个空间里面.

  值类型在运行的时候是存放在堆栈(stack)里面,因此,它们的生存周期一般是根据运行方法的生命周期来确定的,而堆栈是一个自小到大排序,从上往下存放,遵从后进先出(LIFO)的原则的一个数据结构,一般,堆栈是由操作系统来掌控,因此,我们很少干预它的工作.因此,值类型的分配和释放工作基本不会有程序员会关注,除非出现栈溢出.

  引用类型的出现是因为值类型数据总是可能随时被释放,而我们可能希望留一会生存时间,可能以后还能用,这样,就出现了堆的概念,个人理解为堆栈是真正运行的模块,而堆(heap)是一个缓冲存储单元.(堆是一个从大到小,从下往上存放的一个数据结构)

  Class cls ;              //这个动作实际上是在堆栈上为Class类的引用指针分配一个4个字节的空间,目前不指向任何地方

  cls = new Class();  //这个动作是加载代码,然后在堆上开始分配Class()结构大小的内存空间---其中可能包括我们知道的                              方法表和一些前后指针之类的东西

  我们在用的时候实际上是在用堆栈的cls指针来访问堆上的数据---其中包括读取类中的方法表和一些局部数据......

  假设:

  Class cls1,cls2;

  cls1 = new Class();

  实际上在堆栈上分配了2个指针空间(大概为8个字节),其中有一个指针在起作用,因为它new了一个实例,而cls2没有起作用,因此,在编译的时候肯定会出现警告,因为,这样无形中浪费了堆栈的空间.

  假设:

  Class cls1,cls2;

  cls1 = new Class();

  cls2 = new Class();

  bool bl 1 = ReferenceEquals(cls1,cls2)

  bl1 是一个false,因为在堆栈中有两个不同指针,而在堆中生成了两个不同的类,分别由两个不同的指针指向,因此,两个指针的地址不一样,引用地址也不一样.

  假设:

  Class cls1,cls2;

  cls1 = new Class();

  cls2 = cls1;

  bool bl1 = ReferenceEquals(cls1,cls2);

  这个时候,bl1为true,因为在堆中只有一个类,在堆栈中,有两个不同的指针指向它,因此,两个指针的地址不同,可是引用地址相同,因此,ReferenceEquals(cls1,cls2)检测到为同一个地址,返回true.

posted on 2009-03-27 00:34  肖斌  阅读(1698)  评论(10编辑  收藏  举报