2010-07-26 30 views
3

我有JBoss上運行的J2EE項目,2048米的最大堆大小,這是給下負載測試奇怪的結果。我已經基準堆和CPU使用率並取得了以下結果(1系列是堆使用,系列2的CPU使用率):Java堆棧瓶頸 - 如何識別原因?

http://i29.tinypic.com/m9ul1e.png

看起來好像堆被正確並獲得使用垃圾但是,當它到達B時,由於存在可用的堆空間,似乎存在某種瓶頸,但它不會中斷該虛擬線。與此同時,在C處,CPU使用率急劇下降。在此期間,我們還收到「OutOfMemoryError(超出GC開銷限制)」,由於存在可用堆空間,因此對我來說沒有多大意義。

我的猜測是有某種瓶頸,但究竟我甚至無法想象。你會如何建議找出問題的原因?我分析了內存使用情況並注意到有一個類的實例(大約一百萬),但這些實例的總大小相當小(如果我沒有記錯的話,大小約爲50MB)。

編輯:服務器專用於此應用程序,給出的CPU使用率僅適用於JVM(JVM之外不應有任何重要的CPU使用率)。內存使用情況僅適用於堆,它不包含permgen空間。這個問題是可重現的。我主要關心的是圍繞B遇到的限制,對此我還沒有找到合理的解釋。

結論:原來,這是由一堆長時間運行的SQL查詢併發調用引起的。返回的結果集也非常大,可能解釋了OOME。我仍然有爲什麼會出現顯然有些限制在B.

回答

2

從它出現的JVM使用的垃圾收集並行算法清道夫錯誤消息沒有合理的解釋。當a lot of time is spent on GC, but not a lot of the heap is recovered時,該消息隨OOMO錯誤一起丟棄。

來自Sun該文獻沒有指定如果所消耗的總時間的98%將被讀取作爲該過程的CPU利用率98%或CPU本身的。在任一情況下,我已經得出以下推論(具有有限的信息):

  • 垃圾收集器或JVM過程不具有足夠的CPU利用率,最可能是由於其它處理的同時消耗CPU。
  • 垃圾收集器沒有足夠的CPU利用率,因爲它是一個低優先級的線程,而另一個存儲在JVM密集的(但不是CPU密集型)線程在同一時間在做的工作,從而導致未能去分配內存。

根據上述推論(全部,其中一個或全部都不是真),將用戶關心的圖形與應用程序的運行時行爲關聯起來是值得的。換句話說,您可能會發現確定是否啓動了其他進程(發生問題時)或正在運行的應用程序的部分(再次出現問題時)會很有用。

在任何情況下,上面提到的網頁,確實給了一個選項來禁用由GC算法使用的GC開銷限制。如果問題週期性發生並且可以被重現,那麼可能會導致內存泄漏,否則(即偶爾出現),您最好調整GC算法甚至更改它。

+0

第一個要點對我來說沒有意義,因爲CPU使用率下降。第二個似乎是合理的,但我仍然不明白爲什麼內存使用似乎達到了某種它無法通過的最大值?我寧願不改變GC的開銷限制,因爲我有一種感覺,它只會解決症狀而不是原因。 – Zecrates 2010-07-26 18:38:03

+0

如果您的圖只報告JVM的CPU使用情況,而不報告其他進程,則第一點是有意義的。至於GC開銷限制上的標誌,那麼只是禁用開銷;你不能改變它。回到第二點,如果你能確定你是否達到高水位標準,這可能會有所幫助。我的意思是說,圖很可能不是描述整個堆,可能只是它的一部分(它是否也包括permgen?)。 – 2010-07-26 18:54:09

+0

好的,我明白你說的第一點是什麼意思。此圖僅用於JVM的CPU使用情況,系統專用於此應用程序。該圖不包含permgen,那麼你是否暗示它可能是導致OOME的permgen空間?什麼會影響permgen空間,過去我遇到的唯一問題是permgen的加載和卸載問題? – Zecrates 2010-07-27 06:24:51

0

如果我想知道「瓶頸」在哪裏,我只是得到一些stackshots。沒有必要懷疑和猜測,並扮演偵探。他們只會告訴你。

通常,內存問題和性能問題是並存的,所以如果你修復了性能問題,你也將修復內存問題(雖然不是一定的)。