引言
.NET 的内存管理机制,要了解首先应该从内存分配开始,也就是对象的创建环节。对象的创建,是个复杂的过程,主要包括内存分配和初始化两个环节。例如,对象的创建过程可以表示为:
FileStream fs = new FileStream(@"C:"temp.txt", FileMode.Create);
通过 new 关键字操作,即完成了对 FileStream 类型对象的创建过程,这一看似简单的操作背后,却经历着相当复杂的过程和周折。
内存分配
关于内存的分配,我们先了解分配在哪里的问题。CLR 管理内存的区域,主要有三块,分别为:
线程的堆栈,用于分配值类型实例。堆栈主要由操作系统管理,而不受垃圾收集器的控制,当值类型实例所在方法结束时,其存储单位自动释放。栈的执行效率高,但存储容量有限。
GC 堆,用于分配小对象实例。如果引用类型对象的实例大小小于 85000 字节,实例将被分配在GC堆上,当有内存分配或者回收时,垃圾收集器可能会对GC堆进行压缩。
LOH(Large Object Heap)堆,用于分配大对象实例。如果引用类型对象的实例大小不小于 850
00 字节时,该实例将被分配到 LOH 堆上,而 LOH 堆不会被压缩,而且只在完全 GC 回收时被回收。
了解了内存分配的区域,接着我们看看有哪些操作将导致对象创建和内存分配的发生,关于实例创建
有多个 IL 指令解析,主要包括:
newobj,用于创建引用类型对象。
ldstr,用于创建 string 类型对象。
newarr,用于分配新的数组对象。
box,在值类型转换为引用类型对象时,将值类型字段拷贝到托管堆上发生的内存分配。
我们了解了这些基础后,关于堆栈的内存分配机制我们下节再说。