Java 深入理解finalize()方法

时间:2022-10-24 16:19:09
1. 什么是finalize()方法?,
finalize()是Object的protected方法,子类可以覆盖该方法以实现资源清理工作。另外, Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。

2. finalize()方法什么时候被调用?
垃圾回收器 GC 回收对象 进行内存释放前会先调用finalize 方法

3. finalize()与C++中的析构函数的区别?
finalize()与C++中的析构函数不是等同的。
(1) C++中的析构函数调用的时机是确定的。 它是在对象消亡时运行的 (对象离开作用域delete 掉) 。由于C++没有垃圾回收,对象空间手动回收,所以一旦对象用不到时,程序员就应当把 它delete()掉。所以析构函数中经常做一些文件保存之类的收尾工作。
(2) Java中的finalize的调用具有不确定性。 如果内存总是充足的,那么垃圾回收可能永远不会 进行。
4. finalize方法使用的误区
# 对象可能不被垃圾回收。
# 垃圾回收并不等于"析构",finalize不是析构函数。
# 垃圾回收只与内存有关。
# 垃圾回收和finalize都是靠不住的,只要JVM还没有到内存耗尽的地步,它是不会浪费时间进行内存回收的。
5. finalize()方法调用的前提情况
# 所有对象被Garbage Collection自动调用,比如运行System.gc()的时候
# 程序退出时为每个对象调用finalize()方法
# 显式的调用finalize方法
6. 关于finalize()方法的使用
不建议用finalize方法完成“非内存资源”的清理工作,它最主要的用途是回收特殊渠道申请的内存。 建议用于:
(1)清理本地对象(通过JNI(Java Native Interface)调用non-Java程序(C或C++)创建的对象)。
(2)作为确保某些非内存资源(如Socket、文件等)释放的一个补充:在finalize方法中显式调用
其他资源释放方法。
7. finalize的问题
  • 一些与finalize相关的方法,由于一些致命的缺陷,已经被废弃了,如System.runFinalizersOnExit()方法、Runtime.runFinalizersOnExit()方法
  • System.gc()与System.runFinalization()方法增加了finalize方法执行的机会,但不可盲目依赖它们
  • Java语言规范并不保证finalize方法会被及时地执行、而且根本不会保证它们会被执行
  • finalize方法可能会带来性能问题。因为JVM通常在单独的低优先级线程中完成finalize的执行
  • 对象再生问题:finalize方法中,可将待回收对象赋值给GC Roots可达的对象引用,从而达到对象再生的目的
  • finalize方法至多由GC执行一次(用户当然可以手动调用对象的finalize方法,但并不影响GC对finalize的行为)