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()。因為:
- 垃圾回收和finalize()都是靠不住的,只要JVM還沒有快到耗盡內存的地步,它是不會浪費時間進行垃圾回收的。它不會及時執行,所以"never do anything time-critical in finalizer."
- 造成很大性能損失,創建銷毀簡單對象耗時5.6ns,增加一個終結方法需要2400ns。
存在的意義
當忘記調用close方法時,finalizer可以當作最后的防線(原話是safety net,即安全網)。
比如FileInputStream的close方法和finalizer,當私有的FileDescriptor不為空并且也不屬于java.lang.System#in時調用顯示的close方法。Finalizer是JVM內部的守護線程,優先級很低。處理本地對等體(native peer)。(暫時就不去了解native peer是什么了。。)
總結
如果一個類A實現了finalize()方法,那么每次創建A類對象的時候,都會多創建一個Finalizer對象(指向剛剛新建的對象);如果類沒有實現finalize()方法,那么不會創建額外的Finalizer對象。
如果類沒有實現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