2013-06-28 100 views
0

當我們不知道何時可能運行任何給定對象的finalize()方法時,我們需要在java中重寫finalize()方法?我們可以在finalize()中關閉什麼類型的資源?什麼是最佳機會GC會調用finalize()方法嗎?爲什麼我們重寫java中的finalize()方法?

+1

可能是一個doublicate這一個[http://stackoverflow.com/questions/2506488/java-finalize-method-調用](http://stackoverflow.com/questions/2506488/java-finalize-method-call) – Akunosh

+0

這是一個三合一的問題。答案可能是一本專着。 –

+0

我們不會因爲資源一旦使用完畢就關閉,而且我們無法確定何時會調用finalize()。 –

回答

1

當您的類有資源不會被GC清理時,例如文件句柄或數據庫連接,您應該覆蓋finalize。這些資源應該在應用程序代碼中清除,因爲如您所說,我們不知道什麼時候finalize將運行,但是在編程器擰緊的情況下清除終結器中的這些資源也是一個好主意並且將資源打開(如果在運行finalize時資源仍處於打開狀態,則將其作爲警告或作爲錯誤記錄,因爲這意味着應用程序代碼沒有正確清理資源)。

如果程序員正確地清除了對象的資源,.NET允許您禁止終結器。呼籲dispose,但不幸的是,我不認爲Java允許類似的模式。

+0

我們可以在finally塊中做同樣的事情,那麼爲什麼在finalize()method.any真正的上下文適合呢? –

+1

@Jaikant Bhagwan Das問題是程序員可能忘記清理'finally'塊中的資源。我最常見到的用於重寫的'finalize'方法的模式是檢查對象的資源是否仍然打開 - 如果它們是打開的,然後關閉它們,並將其記錄爲錯誤,因爲這意味着在某處該計劃的資源沒有被正確清理。那麼當程序發佈到生產環境時,如果它導致性能問題,則終結器有時會被註釋掉。 –

+0

除了如您所注意的那樣執行'finalize'確實不是一個好主意,用於調試。如果有資源泄漏,它必須被刪除,而不是留下來「敲定」來照顧。 –

0

最好通過手動調用的close方法關閉資源。只有當對象被垃圾收集時纔會調用finalize,在完成對象的使用後可能會很久。

我曾經重寫finalize的唯一原因是在我的應用程序中調試內存使用情況,其中一些對象未被收集。

4

Why would you ever implement finalize()? 這個問題很好。這樣做很少有理由,但是如果沒有正確關閉,可以釋放外部/本地資源的一個例子。即便如此,正確結構化的代碼將避免它的需要。

+0

這就是爲什麼我問?如果沒有真正的用途,那麼finalize()方法在Object類中不是最終的。 –

+3

如果有人願意使用它們,可以提供可選的安全網。即使它們不應該是必需的,但如果人們選擇使用它們,它們可以提供防止內存泄漏的保護。 – resueman

+0

@resueman「防止內存泄漏」與事實完全相反:它們很容易通過復活而變成內存泄漏的* sounce *。你一定意味着「資源泄漏」,他們只是一個非常微弱的臨時措施,並沒有真正的保護。 –

0

首先,定稿的目的是讓對象有機會在對象被垃圾回收之前執行清理。
例如,關閉打開的數據庫連接。

finailze()方法應該被覆蓋爲一個對象包括清理代碼或處理垃圾回收對象之前應該完成的系統資源。

關於當GC調用finalize()方法時,最好的機會是什麼?,有兩種方法,使我們可以要求JVM執行垃圾收集:

  1. Runtime.getRuntime().gc();
  2. System.gc();

我們可以關閉在敲定什麼類型的資源(),答案是兩種情況:

  1. 將所有可用的對象參照null創建對象後 的目的完成。

  2. 使引用變量引用另一個對象:將引用變量與對象分離並將其設置爲引用另一個對象,因此它在重新分配之前引用的對象符合Grabage Collection的條件。

+0

關閉數據庫連接我們也可以在finally塊中執行?爲什麼我依賴於finalize()方法。 –

+0

@JaikantBhagwanDas:try或try-catch後會執行finally塊,它是爲特殊目的而創建的,但GC並不關心是否存在finally塊,當對象符合條件時它將可用被抓住。 – Azad

-1

從我的筆記:

方法命名爲的finalize()被稱爲前的對象是垃圾回收。不需要釋放任何對象,但可能需要釋放一些其他資源(例如打開的文件描述符)。

protected void finalize() throws IOException { 
    if(fd != null) closeIt() ; 
} 

理論上,終結器可能會做一些事情來防止對象被垃圾回收(例如,在某些引用中存儲「this」)。這從來不是一件有用的事情。

與構造函數不同,終結器不會自動鏈接。這是一個非常好的主意,手動把它們連,最好是在終結的末尾:

protected void finalize() { 
    // free resources consumed by this class 
    // chain upward: 
    super.finalize() ; 
} 
相關問題