Java开发之道
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

谬误8 无稽之谈——垃圾回收器可以回收资源而不必手动释放

Java虚拟机提供了垃圾回收机制,通过垃圾回收器可以回收资源,但是Java虚拟机并不能回收所有的资源,垃圾回收器只能回收堆内存中的对象,而不能回收数据库连接对象、输入输出流对象等物理资源,对于这些物理资源必须要手动释放,因此,垃圾回收器可以回收资源而不必手动释放的说法是完全错误的。

可以通过赋值运算符“=”把对象赋值为null来销毁对象。Java虚拟机提供了垃圾回收机制,当对象的生命周期结束后,Java 虚拟机将通过垃圾回收器自动清理不用的对象,释放内存资源。

另外,在Object类中提供了进行垃圾回收的finalize ()方法,该方法的定义如下:

    protected  void finalize () {
 
    }

当Java虚拟机的垃圾回收器确定不存在对该对象的引用时,对象的垃圾回收器就会调用此方法进行垃圾回收,也可以通过重写finalize ()方法,在方法内部编写释放资源的代码,然后通过调用System类的gc ()方法运行垃圾回收器,完成垃圾回收。

示例:

    public class HelloWorld {
      String value = "Hello";                         // 创建并初始化成员变量value
      public static void main (String[] args) {
          HelloWorld world = new HelloWorld ();        // 创建对象world
          System.out. println ("value="+world. value); // 输出类的成员变量value的值
          world = null ;                           // 销毁world对象,因此没有当前对象的引用了
          System.gc();                             // 运行垃圾回收器,调用finalize ()方法
      }
      protected void finalize () {                  // 重写finalize ()方法
          value = null;                            // 销毁value对象
          System.out. println ("value="+value);      // 输出销毁后的value
      }
    }

运行本示例,效果如图4.2所示。

图4.2 销毁value对象前后的效果

注意

一定要先销毁类的实例,如本示例中的 "world=null; ”,然后再调用System类的gc ()方法,才能启动垃圾回收器,并调用finalize ()方法进行垃圾回收,如果没有执行销毁对象的代码 "world=null; ”,而是直接调用System类的gc ()方法,程序是不会启动垃圾回收器的,当然也就不会执行finalize ()方法进行垃圾回收了。

提示

对于数据库连接对象、输入输出流对象等物理资源,是不会被垃圾回收器自动回收的,所以必须要手动进行释放,方法是在try…catch…finally的finally块中编写释放资源的代码。