2012-08-03 50 views
2

在java堆轉儲中我怎麼知道代碼中的哪個/哪個線程導致了轉儲?檢測java中堆轉儲的根本原因

+0

的原因是什麼(這是很多)你所尋找的是使用更多內存的對象,而不是你認爲他們應該做的。我使用YourKit跟蹤分配情況,以便我可以看到哪些代碼創建了大多數數據(或我所關心的數據) – 2012-08-03 08:03:14

+0

如果應用程序的行爲正確,原因可能是最大堆大小太小。 – 2012-08-03 08:04:18

回答

3

用於讀取內存轉儲:

我會建議你試試「蝕內存分析器」從here

另一種選擇(免費)將與JVisualVM(可在$ JAVA_HOME/bin中)來打開此 是與jHat太酷,但已經建議:)

現在,你問的是線程導致堆內存轉儲,而不是如何與內存轉儲... 這要看你是怎麼獲得繼續內存轉儲。 有不同的方法來獲取轉儲。

  1. 在你的過程中,您可以指示JVM產生內存轉儲一旦遇到內存不足的錯誤,在這種情況下,我相信這將是JVM本身。

  2. ,可在外部觸發從MBean堆轉儲創建時給出你有一個JMX Server與JVM一起運行 Example

  3. 你甚至可以使用系統調用(在Linux上)到您的應用程序:kill -3 _YOUR_JAVA_PROCESS_ID_會生成heapdump。

但我很難想象爲什麼你需要這樣的信息。在後面的評論中,您提到了「確切的代碼行」,但這些方式通常是在JVM外部的......您確定需要一行代碼來生成堆轉儲本身,或者您正在嘗試確定真正的問題嗎?

希望這有助於

+0

我在問以下問題:有一個堆轉儲,我如何在它中找到導致錯誤的代碼和線程中的確切代碼行,從而使JVM產生轉儲? – Jim 2012-08-03 07:16:10

+0

啊,我明白了。所以你有一個錯誤,通常是它的OutOfMemory,對吧?在這種情況下,它只是一個堆轉儲分析。如果您使用MAT,它將有可能爲您識別可能的bottelenecks /可疑代碼。通常它歸結爲內存泄漏,但沒有銀彈解決方案。它對於每個系統都不相同。試着看看你有多少種類型的物品,也許有些東西看起來很「怪異」,你會得到一個線索如何進行...... – 2012-08-03 07:20:40

0

嘗試使用Java Heap Analysis Tool(jhat)或jconsole(即在您的JAVA_HOME \ bin中)。

+0

雖然我有興趣找到確切的代碼行。這可以做到嗎? – Jim 2012-08-03 07:05:15

1

在java中創建對象的一些地方,使用它在很多地方和讓GC收集回來。沒有一條線路導致泄漏。

你應該在像MAP這樣的工具中尋找什麼是它們所使用的對象數和堆。選擇每個目標課程,看看爲什麼他們沒有收集垃圾。 (有人拿着比基準多needed-說靜態字段)

您可能會發現從這個頁有用的指令 - 這是使用內存http://scn.sap.com/people/krum.tsvetkov/blog/2007/07/02/finding-memory-leaks-with-sap-memory-analyzer(也MAT主頁鏈接)