2008-08-26 65 views
16

如果我從程序代碼的對象上調用finalize(),當垃圾收集器處理此對象時,JVM仍會再次運行該方法嗎?Java和手動執行完成

這將是一個近似的例子:

MyObject m = new MyObject(); 

m.finalize(); 

m = null; 

System.gc() 

將向finalize()顯式調用使JVM的垃圾收集不運行對象mfinalize()方法?

回答

30

根據這個簡單的測試程序,JVM將仍然使其調用完成(),即使你明確地把它稱爲​​:

輸出是:

開始
定稿!
敲定!

在那裏的每個資源說永遠不會調用finalize()明確,並且幾乎從來沒有實現的方法,因爲有沒有保證,而如果當它被調用。您最好手動關閉所有資源。

1

對於任何給定的對象,JVM永遠不會多次調用finalize方法。不管怎樣,你都不應該依賴最終確定,因爲不能保證它會被調用。如果你調用完成,因爲需要執行清理代碼,那麼不如把它變成一個獨立的方法,使之明確,如:

public void cleanUp() { 
    . 
    . 
    . 
} 

myInstance.cleanUp(); 
6

您必須瞭解垃圾收集器(GC)工作流程以瞭解最終確定的功能。調用.finalize()將不會調用垃圾回收器,也不會調用system.gc。實際上,最終確定的內容將幫助編碼人員將對象的引用聲明爲「未引用」。

GC強制停止JVM的運行操作,這會對性能產生影響。在操作過程中,GC將遍歷所有引用的對象,從根對象(您的主要方法調用)開始。通過手動將對象聲明爲未引用,可以減少暫停時間,因爲它可以降低操作成本,以便通過自動運行聲明對象引用已過時。通過聲明finalize(),編碼器將對象的引用設置爲過時,因此在下次運行GC操作時,GC運行將掃描對象而不使用操作時間。

Quote:「在對對象調用finalize方法之後,不會採取進一步的操作,直到Java虛擬機再次確定不再有任何可以通過任何線程訪問此對象的方式還沒有死亡,其中包括可能由其他對象或類準備完成的可能動作,此時可能會丟棄該對象。「來自Java API Doc對java.Object.finalize();

有關詳細說明,您還可以查看:javabook.computerware