2009-01-06 90 views
4

我的任務是調試Java(J2SE)應用程序,該應用程序在一段時間的活動後開始拋出OutOfMemory異常。我是Java新手,但有編程經驗。我有興趣瞭解如何診斷此類問題的好方法?診斷Java內存問題的策略

到目前爲止,我已經聘用了JConsole來了解正在發生的事情。我有一種預感,那就是有沒有被正確釋放的對象,因此在垃圾回收期間沒有被清理。

是否有任何工具可用於獲取對象生態系統的圖片?你會從哪裏開始?

回答

4

我會從一個適當的Java分析器開始。 JConsole是免費的,但它遠不及那些花錢的功能。我使用JProfiler,這是非常值得的錢。有關更多選項和意見,請參見https://stackoverflow.com/questions/14762/please-recommend-a-java-profiler

+0

謝謝你的擡頭。花了大約30分鐘配置探查器集成後,我能夠在大約5分鐘內找到內存泄漏的來源。感謝這個建議。 – Matty 2009-01-07 16:24:19

4

嘗試使用Eclipse Memory Analyzer或任何其他可以處理Java堆轉儲的工具,然後使用運行內存不足時生成堆轉儲的功能來運行應用程序。

然後分析堆轉儲並查找可疑高對象數。

有關heap dump的更多信息,請參閱這篇文章。

編輯:另外,請注意,您的應用程序可能只是合法需要比您最初想象的更多的內存。您可以嘗試將java最小和最大內存分配增加到更大的內存,然後查看您的應用程序是無限期運行還是稍微進一步。

+0

我希望我可以在另一個線程中直接鏈接到我對EMA的評論,但是我不能推薦這個。 EMA能夠在不到5分鐘的時間內爲我打開一個大約400mb的堆轉儲日誌文件,而jhat花了70多分鐘在它崩潰JVM之前閱讀它(從未能夠完全打開它)。 – 2009-06-18 18:39:01

1

http://www.yourkit.com/download/index.jsp是您需要的唯一工具。 您可以在(1)應用程序開始時間拍攝快照,以及(2)在運行應用程序N段時間之後,然後比較快照以查看內存分配的位置。它還會對OutOfMemoryError拍攝快照,以便您可以將此快照與(1)進行比較。

例如,我必須排除故障的最新項目拋出OutOfMemoryError異常,並且在啓動YourKit之後,我意識到大部分內存實際上正被分配給一些ehcache「LFU」類,重點是我們指定了某些POJO要緩存在內存中,但我們沒有指定足夠的-Xms和-Xmx(開始和最大JVM內存分配)。

我也使用過Linux的vmstat一些Linux平臺沒有啓用足夠的交換,或者不分配連續的內存塊,然後有(與JDK捆綁在一起的)jstat

UPDATE看到https://stackoverflow.com/questions/14762/please-recommend-a-java-profiler

-1

您還可以添加一個 「UnhandledExceptionHandler」 到應用程序的線程。這將捕獲'未捕獲'異常,就像內存不足錯誤,並且您至少會知道引發異常的位置。通常情況下,這不是問題,而是無法滿足的'新'。作爲一個規則,我總是添加UnhandledExceptionHandler到一個線程,如果沒有別的要添加日誌記錄。

2

最新版本的Sun JDK包含VisualVM,它本身就是Netbeans分析器。它工作得很好。