在.net中自动内存管理是由垃圾回收器来是实现,垃圾回收器自动完成对托管堆管理。
什么样对象被垃圾回收器来回收
一个对象不被任何其他对象所引用时,垃圾回收器采用一定的算法在托管堆中遍历所有对象,构成一个对象图,而不可以到达的对象将成为被释放的垃圾对象。
如何回收
每个应用程序都有一组根(指针),指向托管堆中的存储位置,有JIT编译器和CLR运行时维护根指针列表,主要包括全局变量,静态变量,局部变量和寄存器指针等。垃圾收集器就是通过指针列表来实现托管堆中的对象图,当垃圾回收器启动时,它假设所有对象都是可回收的垃圾,然后开始遍历所有的根,将根引用的对象标记为可达对象图中,依次类推,垃圾收集器通过根列表的递归遍历,将能找到的所有可达对象,形成一个可达图。同时不可到达的对象则认为是可回收的对象。这种算法一般称为:标记和清除算法。
何时回收
内存收集器周期性的执行内存清楚工作,一般以下方式启动垃圾收集器:
1.第0代(代龄)对象充满时,
2.强制执行GC.Collect方法,
3.windows报告内存不足,CLR将强制执行垃圾回收。
4.CLR卸载AppDomain时,垃圾回收器将对所有代龄的对象执行垃圾回收。
简单介绍一下代龄:垃圾收集器将托管堆中的对象分为三代:0(容量256KB),1(容量2MB),2(容量10MB),其中第0代对象的回收的效率最高,CLR初始化后,被添加到托管堆中的对象都被定为第0代,当有垃圾回收执行时,未被回收的对象代龄将提升一级,变成第1代对象,而后新建的对象仍为第0代对象。也就是说代龄越小,表示对象越新,通常情况下生命周期越短。因此垃圾收集器总是首先回收第0代的不可到达对象的内存。那对1代对象的收集是什么时候呢?第0代对象内存不足以创建新的对象,同时第1代对象的体积也超出了容量值时,垃圾回收器将同时对0代和1代对象进行垃圾回收。回收后未被收回的1代对象升级为2代对象,未被回收的0代对象升级为1代对象,而后新建的对象仍为第0代。垃圾收集正式上述过程的不断重复。
|