Java学习笔记—— finalize() 方法

8,796 阅读3分钟

1、垃圾回收

2、finalize()的定义和作用

3、finalize()的隐藏问题

4、finalize()方法的一般格式

5、finalize()的执行过程(生命周期)

6、实例

1、垃圾回收

  • Java的垃圾回收器只会释放由我们new出来的内存堆块,那些不是由new出来的“特殊内存”,垃圾回收器是不会管理的。
  • 所谓的特殊内存指通过JNI用C/C++向系统申请的内存,这些内存如果不手动去清除就会一直占据在内存中。
  • 而且,垃圾回收本身就有开销,所以虚拟机不会经常GC,只有当内存快要耗尽的时候JVM才会触发GC。

2、finalize()的定义和作用

由上,Java中的对象并不一定会被全部垃圾回收,当你不想要该对象的时候,你需要手动去处理那些“特殊内存”。

Java 允许定义这样的方法,它在对象被垃圾收集器析构(回收)之前调用,这个方法叫做 finalize( ),它用来清除回收对象。

不建议用finalize()方法完成“非内存资源”的清理工作,但建议用于:
① 清理本地对象(通过JNI创建的对象);
② 确保某些非内存资源(如Socket、文件等)的释放:在finalize()方法中显式调用其他资源释放方法。

3、finalize()的隐藏问题

  • System.gc()System.runFinalization()方法增加了finalize()方法执行的机会,但不可盲目依赖它们
  • Java语言规范并不保证finalize方法会被及时地执行、而且根本不会保证它们会被执行
  • finalize()方法可能会带来性能问题。因为JVM通常在单独的低优先级线程中完成finalize()的执行
  • 对象再生问题:finalize()方法中,可将待回收对象赋值给GC Roots可达的对象引用,从而达到对象再生的目的
  • finalize()方法至多由GC执行一次(用户当然可以手动调用对象的finalize()方法,但并不影响GC对finalize()的行为)

finalize()一般不用!被执行的不确定性太大。不要指望使用finalize()来回收你的对象,它只会在系统进行GC的时候清理特殊内存,不受你的控制!

4、finalize()方法的一般格式

protected void finalize()
{
   // 在这里终结代码
}

关键字 protected 是一个限定符,它确保 finalize() 方法不会被该类以外的代码调用。

5、finalize()的执行过程(生命周期)

当对象变成(GC Roots)不可达时,GC会判断该对象是否覆盖了finalize方法,若未覆盖,则直接将其回收。否则,若对象未执行过finalize方法,将其放入F-Queue队列,由一低优先级线程执行该队列中对象的finalize方法。执行finalize方法完毕后,GC会再次判断该对象是否可达,若不可达,则进行回收,否则,对象“复活”。

具体流程参考:www.cnblogs.com/Smina/p/718…

6、实例

FinalizationDemo.java 文件代码:

public class FinalizationDemo {  
  public static void main(String[] args) {  
    Cake c1 = new Cake(1);  
    Cake c2 = new Cake(2);  
    Cake c3 = new Cake(3);  
      
    c2 = c3 = null;  
    System.gc(); //调用Java垃圾收集器
  }  
}  
 
class Cake extends Object {  
  private int id;  
  public Cake(int id) {  
    this.id = id;  
    System.out.println("Cake Object " + id + "is created");  
  }  
    
  protected void finalize() throws java.lang.Throwable {  
    super.finalize();  //finalize的调用方法
    System.out.println("Cake Object " + id + "is disposed");  
  }  
}

运行以上代码,输出结果如下:

$ javac FinalizationDemo.java 
$ java FinalizationDemo
Cake Object 1is created
Cake Object 2is created
Cake Object 3is created
Cake Object 3is disposed
Cake Object 2is disposed