2011-05-24 66 views
0

在我的程序代碼中有很多線程。當我的程序開始並結束時,句柄的數量不會被釋放。當程序第二次啓動時,手柄的數量增加。每次都發生這種情況。程序的線程數也增加了。任何人都可以告訴我如何釋放手柄?因爲我的程序存在手柄泄漏問題。如何在java中釋放句柄

+2

你是什麼意思的「句柄」?你的程序是否優雅地終止?你使用什麼物體?通常設置一個對象爲'null'將使它成爲垃圾收集的候選對象,但是如果你發佈了一些相關的代碼,它會有所幫助... – mre 2011-05-24 11:48:49

+0

由於代碼非常大,它是一個完整的清理項目,所以我認爲它不會我可以發佈。因此,正如你所說,將它們設置爲null將使它們成爲垃圾收集的候選對象,但有大量的句柄,所以我使用System.gc(),它不起作用 – 2011-05-24 11:53:47

+0

垃圾收集與文件句柄泄漏很少有關 - 所有的GC都會從內存中刪除任何不再被引用的對象。這本質上是Java內部的,並且不會影響外部資源(要注意對象可能有終結器來關閉資源,但這很少見,並且通常被認爲是一個壞主意......)。 – 2011-05-24 11:55:55

回答

5

您沒有關閉正在使用這些句柄的流。任何時候您使用某種I/O資源時,都需要確保它已關閉。經典則應在finally塊來完成,以確保它被稱爲無論發生什麼情況,如:

final FileInputStream in = new FileInputStream("C:/test.txt"); 
try { 
    // Do whatever you want with the stream: 
    // - read from it directly 
    // - call other methods etc. 
    // Just make sure you're really finished with it 
    // by the end of this try block! 
} 
finally { 
    in.close(); 
} 

這同樣適用於數據庫連接,HTTP連接,各種網址資源 - 用close()方法幾乎任何東西。

查看這些實際類型(文件/數據庫/網絡端口)和任何詳細信息(如文件名,遠程主機等)將幫助您追蹤程序的哪些部分未關閉其資源正確。


這是一個好主意,讓try { ... } finally { foo.close(); }成語嵌入到您的編程肌肉記憶,你總是希望處理資源這樣的。這是防止泄漏的唯一可靠方法,應該在第一次編寫代碼時完成,而不是在稍後追查錯誤時完成。

0

除了Andrzej的說法: 檢查您的自定義對象是否覆蓋finalize()方法。如果finalize方法拋出異常,那麼該對象將永遠不會被垃圾收集。

確實需要檢查靜態集合的用法,通常靜態集合是長期存在的。

也許你可以嘗試使用軟引用和弱引用,以便下次發生垃圾回收時,引用它們的對象可能有資格進行垃圾回收。

再次注意:system.gc()是一個請求,而不是一個強制命令,所以它可能不會產生確切的預期數字。

相關問題