垃圾回收器准备释放内存的时候,会先调用finalize()。

  • 对象不一定会被回收。
  • 垃圾回收不是析构函数。
  • 垃圾回收只与内存有关。
  • 垃圾回收和 finalize() 都是靠不住的,只要JVM还没有快到耗尽内存的地步,它是不会浪费时间进行垃圾回收的。

有时当撤消一个对象时,需要完成一些操作。例如,如果一个对象正在处理的是非Java 资源,如文件句柄或window 字符字体,这时你要确认在一个对象被撤消以前要保证这些资源被释放。为处理这样的状况,Java 提供了被称为收尾(finalization )的机制。使用该机制你可以定义一些特殊的操作,这些操作在一个对象将要被垃圾回收程序释放时执行。

要给一个类增加收尾(finalizer ),你只要定义finalize ( ) 方法即可。Java 回收该类的一个对象时,就会调用这个方法。在finalize ( )方法中,你要指定在一个对象被撤消前必须执行的操作。垃圾回收周期性地运行,检查对象不再被运行状态引用或间接地通过其他对象引用。就在对象被释放之前,Java 运行系统调用该对象的finalize( ) 方法。

finalize()方法的通用格式如下:

protected void finalize( )
 {
     // finalization code 
 }

其中,关键字protected是防止在该类之外定义的代码访问finalize()标识符。

在 Java 中,当你创建一个对象时,Java 虚拟机(JVM)为该对象分配内存、调用构造函数并开始跟踪你使用的对象。当你停止使用一个对象(就是说,当没有对该对象有效的引用时),JVM 通过垃圾回收器将该对象标记为释放状态。

当垃圾回收器将要释放一个对象的内存时,它调用该对象的finalize() 方法(如果该对象定义了此方法)。垃圾回收器以独立的低优先级的方式运行,只有当其他线程挂起等待该内存释放的情况出现时,它才开始运行释放对象的内存。(事实上,你可以调用System.gc() 方法强制垃圾回收器来释放这些对象的内存。)

如果你为某个对象定义了finalize() 方法,JVM 可能不会调用它,因为垃圾回收器不曾释放过那些对象的内存。调用System.gc() 也不会起作用,因为它仅仅是给 JVM 一个建议而不是命令。

Gc() 才是垃圾回收器

package com.zth;

class Demo{
  public void finalize() {
    System.out.println("调用 finalize() 方法...");
  }
}

public class Test{
  public static void main(String[] args) {
    Demo f = new Demo();
    Demo f1 = new Demo();
    Demo f2 = new Demo();
    f = null;
    f1 = null;
    f2 = null;
    System.gc();
  }
}

执行结果:

调用 finalize() 方法...
调用 finalize() 方法...
调用 finalize() 方法...