java 與 C 的其中一個差別就在於寫 C 程式時,假如我們 new 了一個物件,同時我們也必須下 delete 來清除它, C 語言的核心并不會判定這個物件是否不再使用,而在程式執行時,需不需要將物件移除,也全都由使用者自行控制。其實這個原意很好,但是寫到大型專案,或是 Multi-Thread 程式時,往往這些物件會變成難以控制,有時候我們甚至會試圖去使用一個已經不存在的指標。
在 Java 中, JVM 幫我們治理這一層,因此當物件不在被使用時, JV M 會在"適當"的時間點將它由記憶體中移除。
所有的物件均繼續 Object ,因此 Object 這個物件中,有一個很有用的 method 叫做 finalize() ,這一個 method 依照定義,當 Garbage Collection 要將這個物件移除前會先呼叫這個物件的 finalize() 。也就是說,當我們在實作我們的 Class 的時候,最好將這一個 method override 。這樣一來,當 Garbage Collection 要清除物件的時候,就會執行到我們自己寫的 finalize()。
因此我們設計了底下這個物件,這個物件在我們建立時,需要帶入一個 int 值,這一個 int 值,而當 finalize() 被執行的時候,他會將這個 int 值列印出來,好讓我們知道 Garbage Collection正預備清除哪一個物件。
public class testobject
{
PRivate int itell;
public testobject()
{
this.itell = 0;
}
public testobject(int i)
{
this.itell = i;
}
public void finalize()
{
System.out.println("testobject id = "+itell);
}
}
接著,我寫了底下這一個 testfinalize.java ,這一個 testfinalize.java 會宣告一個陣列,這一個陣列中,會存放 testobject 物件,屆時 我會將這一個陣列設為 null ,表示我不再使用這一個陣列了。
public class testfinalize
{
public static void main(String argv[])
{
testobject [] testo = new testobject[2];
testo[0] = new testobject(1);
testo[1] = new testobject(2);
testo = null;
System.out.println("finish...");
}
}
執行的結果是
C: empjavajava testfinalize
finish...
C: empjava
希奇,是 garbage collection 沒有執行 finalize() 嗎?? 不是的,是 garbage collection 根本沒有被啟動,在前面說過,garbage collection 會在適當的時機啟動,而這一個 testfinalize 程式很小, JVM 認為不需要執行 Garbage Collection ,因此程式結束,記憶體釋放。
是不是這樣就沒辦法知道 garbage collection 做了時么事情??不是我們還可以透過兩個 method 來建議 JVM 執行 garbage collection,一個是 System.gc(); ,另外一個建議的方式是 Runtime.getRuntime().gc(), System.gc() 也會執行 Runtime.getRuntime().gc() ,不論哪一個,他們都會建議 JVM 去執行另外一個 Thread ,這一個 Thread 會掃瞄所有沒有被用到的物件,將他們清除,并且取得他們所占用的記憶體。
新聞熱點
疑難解答