2012-09-17 25 views
-1

所以,我有這個想法寫一些代碼,可以自動檢測並指出潛在的內存泄漏在測試中,我只是想看看我的想法是否合理,然後纔會遇到實施它的麻煩。是否可以反思性檢查java中的內存泄漏?

本質上,內存泄漏被定義爲越來越多的未使用的引用。在Java中,與C++相比,這種危險顯着減少,因爲我們沒有懸掛指針的危險,或者忘記了delete()等。

因此,這限制了我們可以在內存泄漏Java的。我們可以有一個對象的靜態引用,或者我們可以在當前正在運行的線程中擁有局部引用,就是這樣,對吧?

我的想法是編寫一個查看所有已知項目類文件的例程,並提取所有靜態引用。然後需要將引用「遞歸」下來,並且需要對所有實例引用進行計數。一個對象引用需要一定量的內存,而原語需要一定量的內存,我們可以完成所有工作。你可以觸發這個例程一次,得到一個基線,然後做你認爲導致內存泄漏的事情,然後再次運行例程,並比較結果。可以設置增量閾值,然後您可以手動確定哪些對象有目的地變大,哪些對象變大了,但不應該有。

但是,這是一個測試工具,但是,在我工作的項目中,通常我只能在生產中重現這些錯誤,並且有很多用戶,因此使用真正的分析器並不總是選項。內置此功能可以節省實際運行分析器的時間,並且可以在大多數情況下允許正常操作,除非診斷生產產品時出現問題。

我看到的唯一問題是,當前正在運行的線程中的局部變量不能以這種方式訪問​​,但是,知道該限制,可能需要代碼在測試中註冊這些本地(但是長期引用)的測試類本身,它將持有對靜態變量中那些對象的弱引用,從而允許對引用進行計數。垃圾收集將成爲一個問題,所以基本上,我會通過創建一個未引用的對象來「強制」垃圾收集,這會覆蓋最終確定,以便在收集時通知我的線程,這會導致我的GC檢測器停止阻塞,然後運行檢漏儀。

所以,我的問題是,這聽起來似乎合理嗎?你認爲這會產生有用的結果嗎?

+0

如果可能有人會做到這一點,並且現在賺了很多錢。我認爲你的想法不會產生我現在無法得到的有用結果。 – duffymo

+0

那你如何得到這些結果呢?我之所以想這是因爲我懷疑有內存泄漏,但我不知道從哪裏開始看。 – LadyCailin

+0

我認爲你應該使用Visual VM來查找內存泄漏。 – duffymo

回答

1

由於Java 1.5你有jmap可以打印類直方圖。

2

因此,這限制了我們在Java中可能存在內存泄漏的方式。我們可以有一個對象的靜態引用,或者我們可以在當前正在運行的線程中擁有局部引用,就是這樣,對吧?

號爲備用原因,其中大部分的方法不會檢測到非詳盡列表查看Creating a memory leak with Java

在我工作的項目中,通常我只能在生產中重現這些錯誤,並且有很多用戶,所以使用真正的分析器並不總是一種選擇。內置此功能可以節省實際運行分析器的時間,並且可以在大多數情況下允許正常操作,除非診斷生產產品時出現問題。

你總是可以有生產系統寫一個堆轉儲(Oracle的JVM甚至有一個setting每當一個OutOfMemoryError時寫堆轉儲)。然後,您可以分析這些堆轉儲(有多種工具可供使用,其中一些可通過應用某些啓發式技術自動查找「泄漏嫌疑人」)。