.net垃圾回收器原理

.net中自动内存管理是由垃圾回收器来是实现,GC自动完成对托管堆管理。

l         什么样对象被GC来回收

一个对象不被任何其他对象所引用时,GC采用一定的算法在托管堆中遍历所有对象,构成一个对象图,而不可以到达的对象将成为被释放的垃圾对象。

l         如何回收

每个应用程序都有一组根(指针),指向托管堆中的存储位置,有JIT编译器和CLR运行时维护根指针列表,主要包括全局变量,静态变量,局部变量和寄存器指针等。垃圾收集器就是通过指针列表来实现托管堆中的对象图,当垃圾回收器启动时,它假设所有对象都是可回收的垃圾,然后开始遍历所有的根,将根引用的对象标记为可达对象图中,依次类推,垃圾收集器通过根列表的递归遍历,将能找到的所有可达对象,形成一个可达图。同时不可到达的对象则认为是可回收的对象。这种算法一般称为:标记和清除算法。

l         何时回收

内存收集器周期性的执行内存清楚工作,一般以下方式启动垃圾收集器:

1.        0代(代龄)对象充满时,

2.        强制执行GC.Collect方法,

3.        windows报告内存不足,CLR将强制执行垃圾回收。

4.        CLR卸载AppDomain时,GC将对所有代龄的对象执行垃圾回收。 

简单介绍一下代龄:垃圾收集器将托管堆中的对象分为三代:0(容量256KB),1(容量2MB),2(容量10MB),其中第0代对象的回收的效率最高,CLR初始化后,被添加到托管堆中的对象都被定为第0代,当有垃圾回收执行时,未被回收的对象代龄将提升一级,变成第1代对象,而后新建的对象仍为第0代对象。也就是说代龄越小,表示对象越新,通常情况下生命周期越短。因此垃圾收集器总是首先回收第0代的不可到达对象的内存。那对1代对象的收集是什么时候呢?第0代对象内存不足以创建新的对象,同时第1代对象的体积也超出了容量值时,垃圾回收器将同时对0代和1代对象进行垃圾回收。回收后未被收回的1代对象升级为2代对象,未被回收的0代对象升级为1代对象,而后新建的对象仍为第0代。垃圾收集正式上述过程的不断重复。

 以上都是涉及是关于.net对于托管资源的回收,至于对于非托管的资源(包括数据库连接,文件句柄,网络连接,COM对象等)是利用2种方式(FinalizeDispose)来实现的,具体就不说了。

  

 

 

posted @ 2009-04-12 21:36  jyogou  阅读(1399)  评论(0编辑  收藏  举报