System.gc()與Object.finalize()的區別

finalize()是由JVM自動調用的,你能夠用System.gc(),但JVM不必定會馬上執行,JVM感受內存空間有限時,纔會開始執行finalize(),至於新的對象建立個數和被收集個數不一樣是由於收集的對象只和JVM的垃圾收集策略有關。java

 

finalize()和gc()
(1)問題:finalize()函數是幹嗎的?Java不是有Garbage Collection(如下簡稱gc)來負責回收內存嗎?
回答:
gc 只能清除在堆上分配的內存(純java語言的全部對象都在堆上使用new分配內存),而不能清除棧上分配的內存(當使用JNI技術時,可能會在棧上分配內 存,例如java調用c程序,而該c程序使用malloc分配內存時).所以,若是某些對象被分配了棧上的內存區域,那gc就管不着了,對這樣的對象進行 內存回收就要靠finalize().
舉個例子來講,當java 調用非java方法時(多是c),在非java代碼內部也許調用了malloc()函數來分配內存,並且除非調用那個了 free() 不然不會釋放內存(由於free()是c的函數),這個時候要進行釋放內存的工做,gc是不起做用的,於是須要在finalize()內部的一個固有方法 調用它(free()).
finalize的工做原理應該是這樣的:一旦垃圾收集器準備好釋放對象佔用的存儲空間,它首先調用finalize(),並且只有在下一次垃圾收集過程當中,纔會真正回收對象的內存.因此若是使用finalize(),就能夠在垃圾收集期間進行一些重要的清除或清掃工做.程序員

 

一般,你不能期望finalize( ),你必須建立其它的「清除」方法,而且明確地調用它們。看來,finalize( )只能存在於程序員很難用到的一些晦澀用法裏了。不過,finalize( )還有一個有趣的用法,它並不依賴於每次都要對finalize( )進行調用,這就是對象「終結條件」的驗證。

當你對某個對象再也不感興趣,也就是它能夠被清除時,這個對象應該處於某種狀態,使它佔用的內存能夠被安全地釋放。例如,要是對象表明了一個打開的文 件,在對象被回收前程序員應該關閉這個文件。只要對象中存在沒有被適當清除的部分,你的程序就存在很隱晦的錯誤。finalize( )的價值在於能夠用來最終發現這種狀況,儘管它並不老是會被調用。若是某次

finalize( )的動做使得bug被發現,那你就可據此找出問題所在——這纔是最重要的安全

 1 class Book {  
 2    boolean checkedOut = false;  
 3    Book(boolean checkOut) {  
 4     checkedOut = checkOut;  
 5    }  
 6   void checkIn() {  
 7    checkedOut = false;  
 8   }  
 9   public void finalize() {  
10    if(checkedOut)  
11     System.out.println("Error: checked out");  
12    // Normally, you'll also do this:  
13    // super.finalized();  
14   }  
15   }  
16   public class TerminationCondition {  
17    public static void main(String[] args) {  
18     Book novel = new Book(true);  
19     // Proper cleanup:  
20     novel.checkIn();  
21     // Drop the reference, forget to clean up:  
22     new Book(true);  
23     // Force garbage collection & finalization:  
24     System.gc();  
25    }  
26   }  
相關文章
相關標籤/搜索