1. 程式人生 > >【tij學習筆記】Java finalize()的使用

【tij學習筆記】Java finalize()的使用

依賴 資源釋放 定時 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()的使用