【tij學習筆記】Java finalize()的使用
阿新 • • 發佈:2017-11-16
依賴 資源釋放 定時 java system 使用 pan 靠譜 col
《Java編程思想》中有提到,Java的垃圾回收器並不是那麽靠譜,垃圾回收會占用很大的資源開銷,垃圾回收器很懶,當變量和對象不再被引用、脫離作用域的時候,垃圾回收器會不定時的進行垃圾回收,也就是說,當內存資源緊張的時候,垃圾回收器才會以最快速度主動去回收資源釋放內存,其他時候可能會回收也可能不會。
如果當垃圾回收器工作的時候,會自動調用finalize(),查看Object類的源碼會發現這個方法是個空方法(先不管底層),是不是說這個方法我們可以去重寫呢?
package com.github.hellxz.thinkinjava; public class TestFinalize {public static void main(String[] args) { /* * 創建FinalizeMethod類並調用 */ TestFinalize f = new TestFinalize(); f.finalize(); System.out.println("mian方法結束"); } /* * 重寫了Object類的方法 */ protected void finalize(){ System.out.println("finalize方法執行了"); } }
//輸出:
//finalize方法執行了
//mian方法結束
看了上述代碼,我們證實了Object類的這個方法的確是可以被重寫的,在書中說finalize是在垃圾回收器刪除對象之前調用的方法,那麽修改上述代碼進行測試
package com.github.hellxz.thinkinjava; public class TestFinalize { public static void main(String[] args) { /* * 創建FinalizeMethod類並調用 */ TestFinalize f1= new TestFinalize(); TestFinalize f2 = new TestFinalize(); TestFinalize f3 = new TestFinalize(); TestFinalize f4 = new TestFinalize(); System.out.println("mian方法結束"); } /* * 重寫了Object類的方法 */ protected void finalize(){ System.out.println("finalize方法執行了"); } } //輸出: //mian方法結束
雖然我們創建了這麽多對象,而且都沒有使用,但是重寫的finalize方法並沒有執行,這說明垃圾回收器並沒有回收。Java中有System.gc()來強制垃圾回收器終結動作;為了使代碼更有說服力,修改一下代碼結構,使更直觀
package com.github.hellxz.thinkinjava; public class TestFinalize { public static void main(String[] args) { Apple a1 = new Apple(1); Apple a2 = new Apple(2); Apple a3 = new Apple(3); Apple a4 = new Apple(4); a1 = null; //置空a1 a2 = null; //置空a2 System.gc(); System.out.println("mian方法結束"); } } class Apple{ private int i; public Apple(int i){ this.i = i; System.out.println("apple "+ i +" is created!"); } protected void finalize() throws Throwable { super.finalize(); //調用Object類方法 System.out.println("apple "+ i +" is disposed!"); } } //output: //apple 1 is created! //apple 2 is created! //apple 3 is created! //apple 4 is created! //mian方法結束 //apple 1 is disposed! //apple 2 is disposed!
結論:
1、不要過分依賴finalize方法來執行資源清除工作,垃圾回收器會自動回收資源的
2、finalize不同於c++的析構函數,無需主動釋放內存,想調用可以使用System.gc();
3、finalize用於清除非Java語言占用的內存,以及檢查錯誤
4、垃圾回收器不會一有垃圾就回收內存,除非內存吃緊
【tij學習筆記】Java finalize()的使用