2012-12-05 55 views
5

我在一個4-CPU和32GB存儲器64位機(OS是CentOS的6.3)運行Tomcat。我啓動Tomcat與Java選項-server -Xms1024m -Xmx1024m -XX:PermSize=512m -XX:MaxPermSize=512mJava程序(Tomcat)的保持進食存儲器(RES在頂部)

在開始的時候,RES只是810MB採用頂級,它會持續增加。在此期間,我運行jmap -J-d64 -histo pID來檢查Java內存堆,並且我認爲gc工作正常,因爲堆積峯值爲510MB,gc後爲200MB左右。但是,當頂級RES達到1.1g時,CPU使用率將超過100%,Tomcat將掛起。

使用jstack pid看到轉儲當CPU使用率是100%,一個名爲「虛擬線」線吃掉幾乎100%的CPU。我GOOGLE了,它是JVM gc線程。所以我的問題是:當gc工作正常時,爲什麼res保持增長?我怎麼能解決這個問題?謝謝。

+0

我看你已經接受我的答案。出於好奇,請你簡單描述一下究竟是什麼原因,究竟有什麼幫助? –

+0

當gc線程佔用超過100%的cpu時,我腦海中第一個想到的就是內存泄漏。但事實是-Xmx1024m對我的應用來說太小了......我犯了一個錯誤:(我將內存增加到2048m (-Xmx2048m),和頂級的RES時,它的最高1.2克不增加......... – ing

+1

那麼我想通過@digitaljoel答案是比較合適的接受 –

回答

1

如果垃圾收集線程正在以100%旋轉,那麼它很可能正在嘗試執行垃圾收集,但沒有收集任何對象,因此您正處於垃圾收集死亡螺旋中,但它一直試圖運行,但無法釋放任何內存。

這可能發生,因爲你在你的程序有內存泄漏,或者是因爲你只是不給VM足夠的內存來處理你經常在使用過程中加載的對象的數量。這聽起來像你有足夠的空間來增加堆大小。這可能只會延長到達死亡螺旋之前的時間量,或者可能會讓您進入奔跑狀態。你會想要進行一段時間的測試,以確保你不會拖延不可避免的。

+0

感謝您的回覆。 pmap/top命令顯示內存不斷增加,但jmap顯示該堆在gc後僅爲200MB左右,其峯值約爲550MB。除了堆以外,Java中的任何其他類型的內存都可能導致泄漏? – ing

+0

即使gc線程爲100%,堆仍然在200MB左右?你可以附加jvisualvm在運行時查看垃圾收集模式和堆空間嗎? – digitaljoel

+0

,我將內存增加到2048m(-Xmx2048m),而頂部的RES在1.2g時不會增加。在詢問之前,我應該多試一次。感謝您的幫助。 – ing

2

可能是一個PermGen的泄漏。如果你說你的堆保持在〜500Mb,並且-XX:MaxPermSize被設置爲512Mb,那麼完整的permgen會給你大約1GB的內存使用量。

如果您在程序生命週期後期加載的jsps有很多(如很多!),或者您已經使用了很多String.intern(),可能會發生這種情況。

關注這個主題做進一步的調查:How to dump Permgen?

而且這個線程調諧GC掃PermGen的What does JVM flag CMSClassUnloadingEnabled actually do?

+0

爲偉大的鏈接+1。 – digitaljoel