黑马程序员--值类型和引用类型 (05)

来源:互联网 发布:逆战刷复活币软件 编辑:程序博客网 时间:2024/05/21 10:53

----------------------ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------


一. 引用类型和值类型

 1. 栈(Stack)和堆(Heap)

      在了解引用类型和值类型之前我们先来了解变量是怎么分配内存,并且知道什么是栈内存和堆内存。

                 ① 在C#程序中,当你声明一个变量,将在内存中分配一块内存。这块内存分为三部分:1,变量名;2,变量类型;3,变量值。.NET中有两种类型的内存:栈内存和堆内存,其中变量分配的内存类型要依据你的变量的数据类型。

下面通过一个例子来说明一下什么是栈和堆,以及变量是怎么分配到相应的内存上的:         

          实例代码:

          public void Method1()
    {
      //第一行 Line1
      int i= 4;
      //第二行 Line2
      int y= 2;
     //第三行 Line3
      class1 cls1=new class1();//class1是一个类,并且创建了一个这个类型的变量cls1
    }

   内存分析图例:


上面Method1()方法中一共有三行代码,分别声明了三个变量(i,j,cls1),我们逐一来看看它们是怎么在栈和堆上分配内存的:

    第1行:当这行代码执行时,编译器为它分配一小块栈内存(因为变量i是值类型)。运行时栈负责提供程序所需的内存;

    第2行:程序继续执行。如同名字一样,栈在第一块内存的顶部分配了一块内存。你也可以认为是模块或零件一块一块叠起来;内存的分配与释放遵循后进先出(后进先出,LIFO)逻辑,换句话说,内存只能在示例中i内存块的顶部分配或释放。(y变量和i变量一样是分配在栈内存上)

    第3行:在第3行,我们创建了一个对象。当该行执行时,编译器在栈上创建了一个指针,真实的对象存储在另一种叫“堆”的内存中。"堆"并不跟踪运行 内存,它更像一堆随时可以访问的对象。堆用于动态分配内存。这里需要着重说明的是引用指针是分配在栈上。声明Class1 cls1时并不会给Class1的实例分配内存,而是分配一个栈变量cls1(里面放的是Class1类型的对象地址),然后把它指向“堆”。

    退出方法:当方法退出时,它释放了栈上所有内存变量。换句话说,栈上所有的"Int"变量都依据后进先出的逻辑被释放掉了。要注意,此时不会释放堆内存,这种内存稍后会被“垃圾收集器”释放。

总结:内存分配: →值类型变量分配在栈中的,而且变量存放的内容是实际值;

                 →引用类型变量是分配在堆中,而栈中是保存了该对象的引用(地址)。

       2.引用类型和值类型

           ①现在我们明白了栈和堆,接下来看值类型和引用类型。值类型的数据和内存在同一个位置,而引用类型是一个指向内存的指针。

    下面示例是一个整型数据类型变量i被赋给另一个整型数据类型变量j。它们的内存值都分配在栈上。当我们把一个int值分配给另外一个int值时,需要创建一个完全不同的拷贝。换句话说,你可以改变其中任何一个而不会影响另外一个。这种数据类型被称为值类型。

         

      

       而当我们创建一个对象,并把一个对象赋给另外一个对象时,它们的指针指向相同的内存(如下图,当我们把obj赋给obj1时,它们指向相同的内存)。换句话说,我们改变其中一个,会影响到另外一个,这种类型称为引用类型。

           


           ② 引用类型和值类型区别        

      1.内存分配: 值类型是分配在栈中的;而引用类型是分配在堆中。
      2.效率:     值类型效率高,不需要地址转换;引用类型效率较低,需要进行地址转换。
      3.内存回收: 值类型使用完后立即回收;引用类型使用完后不立即回收,而是交给GC处理回收。
      4.赋值操作: 值类型是创建一个新对象;引用类型创建一个引用。

 ----------------------ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------



原创粉丝点击