finalize()方法

来源:互联网 发布:60数据库海盗的帽子 编辑:程序博客网 时间:2024/05/30 21:58

1.finalize()方法基本概念

finalize()方法是在Object类中定义的protected方法,垃圾回收器要回收对象的时候,首先要调用这个类的finalize方法进行一些必要的清理工作,只有到下一次再进行垃圾回收动作的时候,才会真正释放这个对象所占用的内存空间,子类可以覆盖该方法以实现资源清理工作。

2.finalize()方法作用

之所以在Java语言中引入finalize()方法,主要是由于垃圾收集器只知道那些显示地经由new分配的内存空间,对于通过JNI等获取的特殊的内存区域,垃圾收集器无法直接释放,此时需要借助finalize()在在垃圾回收前做一些必要的清理工作。
特殊的区域:
1)利用C/C++中的方法如malloc()获取的内存,需要利用finalize()调用本地方法中的free()方法释放相应资源;
2)文件资源/网络资源等,这些资源不属于垃圾回收器的回收范围。
注意
1)finalize()与C++中的析构函数不是对应的。C++中的析构函数调用的时机是确定的(对象离开作用域或delete掉),但Java中的finalize的调用具有不确定性;
2) 对象可能不被垃圾回收,Java语言规范并不保证finalize方法会被及时地执行、而且根本不会保证它们会被执行;
3)finalize方法可能会带来性能问题。因为JVM通常在单独的低优先级线程中完成finalize的执行;
4)对象再生问题:finalize方法中,可将待回收对象赋值给GC Roots可达的对象引用,从而达到对象再生的目的;
5)finalize方法至多由GC执行一次;
6)System.gc()与System.runFinalization()方法增加了finalize方法执行的机会,但不可盲目依赖它们。

3.finalize()方法执行机制

大致流程:当对象变成(GC Roots)不可达时,GC会判断该对象是否覆盖了finalize方法,若未覆盖,则直接将其回收。否则,若对象未执行过finalize方法,将其放入F-Queue队列,由一低优先级线程执行该队列中对象的finalize方法。执行finalize方法完毕后,GC会再次判断该对象是否可达,若不可达,则进行回收,否则,对象“复活”。
详细流程:
涉及到两类状态空间,一是终结状态空间 F = {unfinalized, finalizable, finalized};二是可达状态空间 R = {reachable, finalizer-reachable, unreachable}。各状态含义如下:

unfinalized: 新建对象会先进入此状态,GC并未准备执行其finalize方法,因为该对象是可达的finalizable: 表示GC可对该对象执行finalize方法,GC已检测到该对象不可达。正如前面所述,GC通过F-Queue队列和一专用线程完成finalize的执行finalized: 表示GC已经对该对象执行过finalize方法reachable: 表示GC Roots引用可达finalizer-reachable(f-reachable):表示不是reachable,但可通过某个finalizable对象可达unreachable:对象不可通过上面两种途径可达

状态变迁图
这里写图片描述

4. 参考文献

1)java finalize方法总结、GC执行finalize的过程
2) JVM内存回收之finalize()方法

0 0
原创粉丝点击