值类型,引用类型
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即分配在堆上。
垃圾回收
堆上的内存没有引用会在垃圾回收的时候回收,垃圾回收会暂停其他线程,会压缩重排堆内存以减少碎片。
装箱拆箱
装箱会在堆上分配内存,把栈上的值拷贝的堆上。
拆箱会在栈上分配对象,把堆上的内存拷贝到栈上。栈上的类型和拆箱的类型不一致会报错。