C#内存管理

值类型,引用类型

string,class为引用类型,其他是值类型。值类型分配在栈上[1],引用类型分配在堆上。


堆栈

值类型分配在栈上,局部变量直接存储值。引用类型分配在托管堆,栈上存储一个地址在局部变量引用堆内存。

例如:

Person foo = new Person();

foo存储一个4字节地址,引用堆内存Person分配的空间。

int bar = new int(); 

因为bar是值类型,所以new分配在栈上[2],并且值类型bar直接存储的数据。

[1]《深入理解C#》中提到, 值类型一定分配在栈上并不准确。值类型是跟声明的对象一起放在一起存储的,作为引用类型class的成员的时候跟着class放在堆上。

[2]这点和C++语言不同,new是堆分配关键字,调用new即分配在堆上。


垃圾回收

堆上的内存没有引用会在垃圾回收的时候回收,垃圾回收会暂停其他线程,会压缩重排堆内存以减少碎片。

装箱拆箱

装箱会在堆上分配内存,把栈上的值拷贝的堆上。

拆箱会在栈上分配对象,把堆上的内存拷贝到栈上。栈上的类型和拆箱的类型不一致会报错。