回收无用资源的方法
回收无用资源的方法
l Fina
在上一篇文章中我分配使用资源一共五步,我们已经知道了GC是如何释放无用对象的内存了。但是它怎么实现第四步清空资源使用状态、释放利用到的一些非内存的系统资源呢?.NET引入了Fina
GC在无用单元回收时一旦发现某个对象有Fina
我们可以用两种方法来写自己的Fina
代码1 |
pub {
pub { }
protected override void Fina {
Console.WriteLine(“Fina } } |
使用这种方法时要注意一点,.NET不会帮你做调用基类的Fina
代码2 |
pub {
pub { }
protected override void Fina {
Console.WriteLine(“Fina
base.Fina } } |
另外一种方法就是析构函数。C#中的析构函数不同于C++。我们看下面的代码:
代码3 |
pub {
pub { }
~SomeClass() {
Console.WriteLine(“Fina } } |
它等同于代码2。
使用Fina
GC是如何实现Fina
当托管堆的内存不足的时候,GC开始对堆进行回收。GC回收一个对象前,先检查Fina
对象G和对象E不在根的范围之内,被回收。对象F和对象C由于需要Fina
这时对象F和对象C不再是根的一部分,如果此时GC进行回收,将会被认作无用对象进行回收,回收后如下图:
上面简单描述了Fina
l Generation
每次都对整个对进行搜索,压缩是非常耗时的。微软总结了一些过去的开发中出现的现象,其中有一条就是,越是新的对象,越是最快被丢弃不再使用。微软根据这个经验在内存回收中引入了Generation的概念,我此处暂时将其翻译成代。托管堆开始的时候是空的,程序启动开始在其中分配对象,这时候的对象就是第0代(Generation 0)对象。如下图:
接下来,到托管堆空间不足,GC进行了第一次回收,剩下的没有被回收的对象就升为第一代,之后再新分配的对象就是第0代(图甲)。再之后GC再进行回收的话只回收第0代,未被回收的第0代升级为第一代,原来的第一代升级为第0代(图乙)。
GC缺省的代(Generation)最高就是2,升级到第二代就不会再升级了。那什么时候GC回收第一,第二代呢?当GC回收完第0代后,发现内存空间还不够,就会回收第一代,回收完第一代,还不够,就回收第二代。
这一篇也写了不少了,所以下一篇再继续,下一篇写WeakReference和如何在自己的代码中控制GC的动作。