2011-12-02 264 views
51

我在程序上運行了一個堆轉儲。當我在內存分析工具中打開它時,發現org.logicalcobwebs.proxool.ProxyStatementjava.lang.ref.Finalizer佔用大量內存。這是爲什麼?是內存泄漏?爲什麼java.lang.ref.Finalizer吃了這麼多內存

screenshot

+0

「圖片」鏈接轉到看起來是你的twitter個人資料。 –

+0

@ R.MartinhoFernandes我認爲它可以看到他用Twitter發佈的圖片。 – Oliver

回答

49

一些類實現Object.finalize()方法。重寫此方法的對象需要由後臺線程調用終結器調用,並且在這種情況發生之前無法清理它們。如果這些任務很短,而且不會丟棄其中的許多,那麼這一切都會很好。但是,如果要創建大量這些對象和/或它們的終結器需要很長時間,則需要完成對象的隊列。這個隊列有可能用完所有的內存。

的解決方案是

  • 如果你可以(如果你正在寫的類的對象)不使用的finalize()d對象
  • 使敲定很短的(如果你要使用它)
  • 不要每次都放棄這樣的對象(嘗試重新使用它們)

的最後一個選項可能是最適合你,你正在使用現有的庫。

+12

選項#4 - 避免使用(over-)使用終結器的庫。 –

+3

選項#1的變體;) –

+0

也許問題是Finalizer線程的原因。 一個類重寫finalize methond,導致Finalizer線程死鎖 – fuyou001

7

從我能做出來的事情來看,Proxool是一個JDBC連接的連接池。這表明問題在於你的應用程序正在濫用連接池。而不是在語句對象上調用close,您的代碼可能會丟棄它們和/或它們的父連接。 Proxool依靠終結器來關閉底層驅動程序實現的對象......但是這需要那些Finalizer實例。這也可能意味着,您正在導致連接更頻繁地打開/關閉(實際)數據庫連接,這會影響性能。

因此,我建議您檢查泄漏的ResultSet,Statement和/或Connection對象的代碼,並確保您在finally塊中關閉它們。


看着內存轉儲,我期望你關心的是898,527,228字節在哪裏。絕大多數由終止器對象保留,其ID爲2aab07855e38。如果你仍然有轉儲文件,看看Finalizer指的是什麼。它看起來比Proxool對象更有問題。

+0

謝謝,但我不能找到JDBC連接輪詢memoy泄漏的原因 – fuyou001

+0

嗯,我不能,除非我看到你的源代碼。 (而且我不準備花時間拖網通過它......) –