Item 7: Avoid finalizers

Finalizers are unpredictable, often dangerous, and generally unnecessary.

根据 Java 文档,finalize() 是一个用于释放非 Java 资源的方法。但是,JVM 有很大的可能不调用对象的finalize() 方法,因此很难证明使用该方法释放资源是有效的。

中文版第二段翻译有个错误,原著是"C++ programmers are cautioned not to think of finalizers as Java’s analog of
C++ destructors.",第二版翻译成了「C++程序员被告知不要把终结方法当做C++析构器的对应物」。原文表达的应该是,C++程序员学习Java的时候要注意Java的finalize()不等同于C++中的析构方法。

最好不要用

finalize()Object类的空方法。
这文章说了一般情况不要手动调用finalizer()。因为:

  1. 垃圾回收和finalize()都是靠不住的,只要JVM还没有快到耗尽内存的地步,它是不会浪费时间进行垃圾回收的。它不会及时执行,所以"never do anything time-critical in finalizer."
  2. 造成很大性能损失,创建销毁简单对象耗时5.6ns,增加一个终结方法需要2400ns。

存在的意义

  1. 当忘记调用close方法时,finalizer可以当作最后的防线(原话是safety net,即安全网)。
    比如FileInputStream的close方法和finalizer,当私有的FileDescriptor不为空并且也不属于java.lang.System#in时调用显示的close方法。Finalizer是JVM内部的守护线程,优先级很低。

  2. 处理本地对等体(native peer)。(暂时就不去了解native peer是什么了。。)

总结

  1. 如果一个类A实现了finalize()方法,那么每次创建A类对象的时候,都会多创建一个Finalizer对象(指向刚刚新建的对象);如果类没有实现finalize()方法,那么不会创建额外的Finalizer对象。

  2. 如果类没有实现finalize方法,那么进行垃圾回收的时候,可以直接从堆内存中释放该对象。这是速度最快,效率最高的方式。


总体来说这一条我不怎么懂。

See also:
http://www.07net01.com/2014/09/189155.html
http://www.linuxidc.com/Linux/2015-01/111989.htm
http://blog.csdn.net/carolzhang8406/article/details/6705831

你可能感兴趣的:(Item 7: Avoid finalizers)