C#中的内存管理(二)存储区域划分

首先,我们先了解一下数据在内存中的存储方式,根据变量值的生存周期,可以分为静态存储区和动态存储区。如下:

所谓静态存储区是指在程序运行期间分配固定的存储空间的方式,而动态存储区是指程序运行期间根据需要进行动态分配存储空间的方式。

静态变量和全局变量存储在静态存储区,在程序开始执行时给全局变量分配存储区,程序执行完毕后释放。在程序执行过程中它们占据固定的存储单元,而不是动态地进行分配和释放。

动态存储区主要存储一下数据:

1、函数形式参数。在调用函数时给形参分配存储空间。

2、自动变量。

3、函数调用时的现场保护和返回地址。

这里,我们习惯把动态存储区分为堆区和栈区。栈区由系统自动管理释放,堆区由GC进行管理释放。

了解了数据的存储方式,我们继续了解C#中的数据类型。

C#中的所有数据类型都可以分为两类:值类型和引用类型。它们的区别来源于它们的复制方式:值类型的数据总是被值复制;而引用类型的数据总是被引用复制。

值类型包含值,换言之,变量引用的位置就是值在内存中实际存储的位置。因此,将第一个变量的值赋给第二个变量会在新变量的位置创建原始变量的值的一个内存副本。相同值类型的第二个变量不能引用和第一个变量相同的内存位置。所以,更改第一个变量的值不会影响第二个变量的值。

引用类型和引用它们的变量指向数据存储位置。引用类型并不直接存储值,它们存储的是对一个内存位置的引用(内存地址)。换言之,当我们创建一个引用类型的变量时,是创建了一个指向堆内存块的引用。如下:

这里需要注意的是,引用类型在复制的时候,复制的是地址的内存副本。无论引用类型所引用的内存地址块有多大,实际上传递的只是存储在内存栈上的地址,所以,引用类型的复制效率相比值类型更高。

特殊说明:

1、string类型为引用类型,等号操作相当于new操作。

2、数组是引用类型,无论数组成员是什么类型。

3、C#中所有引用类型的复制都是一种浅复制操作,想要实现深度复制,类型需要实现IClone接口。

4、为引用类型变量申请的存储区由CLR中的垃圾回收机制进行回收,但并不是所有的类型都会自动回收。如:非托管变量。

猜你喜欢

转载自blog.csdn.net/luoye4321/article/details/35354619