CLR 管理内存的区域主要有三块:
一:
线程的堆栈 ,用于分配值类型实例。堆栈主要有操作系统管理,不受垃圾收集器的控制,当值类型实例所在的方法结束时,其存储单位自动释放。栈的执行效率高,但存储容量有限。
二:
GC 堆,用于分配小对象实例。如果引用类型对象的实例小于 85000 字节,实例将被分配在 GC 堆上。当有内存分配或者回收时,垃圾收集器会对 GC 对进行压缩。
三:
LOH(Large object heap) ,用于分配大对象实例。 LOH 堆不会被压缩,而且只有在完全 GC 回收时才会被回收,这种设计方案是对垃圾回收性能的优化考虑。
GC 如何判断某个对象为垃圾
每个应用程序有一组根(指针),根指向托管堆中的存储位置,由 JIT 编译器和 CLR
运行时维护根指针列表,主要包括全局变量、静态变量、局部变量和寄存器指针等。
当垃圾收集器启动时,它假设所有对象都是可回收的垃圾,并开始遍历所有的根,将根引用的对象标记为可达对象添加到可达对象图中,在遍历过程 中,如果根引用的对象还引用着其他对象,则该对象也被添加到可达对象图中,依次类推,垃圾收集器通过根列表的递归遍历,将能找到所有可达对象,并形成一个 可达对象图。同时那些不可达对象则被认为是可回收对象,垃圾收集器接着运行垃圾收集进程来释放垃圾对象的内存空间。
垃圾收集器何时启动:
( 1 )内存不足溢出时,更确切地应该说是第 0 代对象充满时。
( 2 )调用 GC.Collect 方法强制执行垃圾回收。
( 3 ) Windows 报告内存不足时, CLR 将强制执行垃圾回收。
( 4 ) CLR 卸载 AppDomain 时, GC 将对所有代龄的对象执行垃圾回收。
( 5 )其他情况,例如物理内存不足,超出短期存活代的内存段门限,运行主机拒绝分配内存