很多人现在可能要问为什么要设置两种内存分配形式呢?难道就不能用一种内存分配形式完成内存分配吗?
如果你仔细观察上图,你就会知道int变量是分配在堆栈上的,因为编译器已经知道它们可以存储多少数据(-2,147,483,648到2,147,483,647),涉及到对象时,编译器不知道需要多少内部空间,因此在堆上分配相同大小的空间。
换句话说就是,如果不知道数据大小或是动态变化的,就需要分配到堆上,如果数据大小是确定的,就分配到堆栈上。
图4 知道变量大小时分配到堆栈上,不知道变量大小时分配到堆上
值类型和引用类型
值类型指的是在相同的位置同时容纳数据和内存的类型,而引用类型是借助一个指针指向内存位置。下面是一个简单的命名为i的整数数据类型,其值是由另一个命名为j的整数数据类型赋予的,这两个内存值都是基于堆栈分配的。
当我们将一个int值赋给另一个int值时,它创建一个完全不同的拷贝,换句话说就是,你修改其中一个值不会引起另一个值也发生变化,这种数据类型就叫做值类型。
图5 值类型:一个值的变化不会引起另一个值变化
当我们将一个对象赋值给另一个对象时,它们指向相同的内存位置,如下图所示,当我们将obj赋值给obj1时,它们指向的内存位置是一样的。换句话说就是,如果我们修改了其中一个对象,另一个对象也会受到影响,这种类型就叫做引用类型。
图 6 引用类型:一个对象的变化会引起另一个对象的变化
哪一个数据类型是值类型和引用类型呢?
在.Net中,根据数据类型不同,变量可能是基于堆栈分配的,也可能是基于堆分配的,String和Objects是引用类型,其它.Net数据类型是基于堆栈分配的,下图更详细地进行了解释。
图 7 引用类型和值类型对应.Net中的数据类型