2012-12-07 48 views
2

我有一個主要用作WebService的Grails應用程序。它提供了一種非常自定義類型的緩存,它將對象存儲在併發哈希映射中幾秒鐘,並可能在消息被另一個線程處理之前組合消息。經過幾個月的運行沒有問題,PermGen空間最終達到其最大值,我需要重新啓動服務器以防止OOMError異常。PermGen問題 - Groovy GString實例字符串?

我不認爲我的問題與泄漏的類加載器有關,這似乎是大多數PermGen問題的原因。我從來沒有重新部署這個應用程序。 PermGen正在從正常使用中填滿。

我有一種感覺,我的問題可能是由於我的應用程序正在處理大量的唯一字符串。我的應用程序正在大量使用GString的兩個記錄和處理存儲在HashMap中,像這樣前:

mOrig.msg += mNew.msg 
log.debug("Sending combined message: ${mOrig.msg}") 

我的問題是GString的或哈希映射條目是否使用中的String.intern()。如果是這樣,我認爲這將解釋爲什麼我的PermGen空間正在填滿。如果確實如此,那麼處理這個問題的最好方法是什麼?我已經增加了JVM參數中的PermGen空間量。但是,它只是延長了不可避免的。

我使用Eclipse Memory Analyzer比較一個月使用後的堆轉儲。雖然這並沒有告訴我有關PermGen使用情況的很多信息,但很明顯,兩個堆之間的最大區別是字符串和散列表條目的數量。

Class Name          | Objects | Shallow Heap 
-------------------------------------------------------------------------- 
               |   |    
char[]           | +1,731 |  +268,984 
byte[]           |  +35 |  +142,240 
java.util.HashMap$Entry      | +1,684 |  +80,832 
java.lang.String        | +1,675 |  +67,000 
org.apache.tomcat.util.buf.ByteChunk   |  +202 |  +12,928 
org.apache.tomcat.util.buf.MessageBytes  |  +146 |  +11,680 
org.apache.tomcat.util.buf.CharChunk   |  +162 |  +9,072 
java.lang.Object[]        |  -31 |  +7,840 
java.text.DecimalFormat      |  +32 |  +6,912 
int[]           |  +87 |  +6,824 
java.lang.String[]        |  +68 |  +5,872 

沒有人有一個想法可能怎麼回事,如何解決這一問題?我想避免每幾周/幾個月重新啓動Tomcat。

謝謝!

更新:從jmap -permstat添加輸出。有誰知道如何閱讀這個?

29045 intern Strings occupying 4025008 bytes. 
class_loader classes bytes parent_loader alive? type 

<bootstrap>  2221 12948256   null   live <internal> 
0x00002aaac0c40048  1  1952 0x00002aaabe2108a8  dead sun/reflect/[email protected] 
0x00002aaac0c3c388  10  211456 0x00002aaac04f0cc8  dead org/codehaus/groovy/runtime/callsite/[email protected] 
0x00002aaac1a2c698  1  3112 0x00002aaabe2108a8  dead sun/reflect/[email protected] 
0x00002aaac0159380  1  3128 0x00002aaac04f0cc8  dead sun/reflect/[email protected] 
0x00002aaac0158a28  1  3096 0x00002aaac04f0cc8  dead sun/reflect/[email protected] 
0x00002aaac1dfa188  1  3248 0x00002aaac04f0cc8  dead sun/reflect/[email protected] 
0x00002aaac1a2f910  1  1952 0x00002aaabe2108a8  dead sun/reflect/[email protected] 
0x00002aaac0c6e390  12  239656 null   dead org/codehaus/groovy/runtime/callsite/[email protected] 
0x00002aaac1df0a68  1  3200 0x00002aaac0afd9b8  dead sun/reflect/[email protected] 
0x00002aaac1a2db68  1  3112 0x00002aaabe2108a8  dead sun/reflect/[email protected] 
0x00002aaac1a36f58  1  3112 0x00002aaabe2108a8  dead sun/reflect/[email protected] 
0x00002aaac1df9688  1  1952  null   dead sun/reflect/[email protected] 
0x00002aaac0171e70  1  1968 0x00002aaac04f0cc8  dead sun/reflect/[email protected] 
0x00002aaac1979200  1  1952  null   dead sun/reflect/[email protected] 
0x00002aaac01712a8  1  1952 0x00002aaac04f0cc8  dead sun/reflect/[email protected] 
0x00002aaac1dec140  1  3096 0x00002aaac04f0cc8  dead sun/reflect/[email protected] 
0x00002aaac197ad80  1  1952  null   dead sun/reflect/[email protected] 
0x00002aaac1df13e8  1  3120  null   dead sun/reflect/[email protected] 
0x00002aaac1a2f1a0  1  1952 0x00002aaabe2108a8  dead sun/reflect/[email protected] 
0x00002aaac197c380  1  1952  null   dead sun/reflect/[email protected] 
0x00002aaac0c451c0  1  1952 0x00002aaabe2108a8  dead sun/reflect/[email protected] 
0x00002aaabe2183b8  4  14192  null   dead javax/management/remote/rmi/[email protected] 
0x00002aaabfd24688  1  1952 0x00002aaac04f0cc8  dead sun/reflect/[email protected] 
0x00002aaabecd6250  2  19984 0x00002aaabe2108a8  dead org/apache/catalina/loader/[email protected] 
0x00002aaabe217da0  94  900176 0x00002aaabe210930  dead sun/misc/[email protected] 
0x00002aaac0170f68  1  1952 0x00002aaac04f0cc8  dead sun/reflect/[email protected] 
0x00002aaac0c43bc0  1  1952 0x00002aaabe2108a8  dead sun/reflect/[email protected] 
0x00002aaac0c45d60  1  3112 0x00002aaabe2108a8  dead sun/reflect/[email protected] 
0x00002aaac1df0e68  1  1968  null   dead sun/reflect/[email protected] 
0x00002aaac01716b8  1  1952 0x00002aaac04f0cc8  dead sun/reflect/[email protected] 
0x00002aaac1a35c58  1  3112 0x00002aaabe2108a8  dead sun/reflect/[email protected] 
0x00002aaac0c462e0  1  1952 0x00002aaabe2108a8  dead sun/reflect/[email protected] 
0x00002aaac0c87750  1  1968  null   dead sun/reflect/[email protected] 
0x00002aaac1a2e4b0  1  3112 0x00002aaabe2108a8  dead sun/reflect/[email protected] 
0x00002aaabfd246f0  1  3128 0x00002aaac04f0cc8  dead sun/reflect/[email protected] 
0x00002aaac1de9830  1  3136  null   dead sun/reflect/[email protected] 
0x00002aaac1982680  1  3120  null   dead sun/reflect/[email protected] 
0x00002aaac0171a60  1  3112  null   dead sun/reflect/[email protected] 
+1

我可能會將此問題發送到[Groovy用戶郵件列表](http://groovy.codehaus.org/Mailing+Lists),因爲您可能會得到更快更明確的回覆。 –

回答

1

不,Groovy不會實習字符串(與GString或其他任何東西)。我建議你使用jmap -permstat來得到一些有關你的PermGen食物的信息。

+0

我已更新該帖子以包含jmap -permstat的輸出。我不確定如何閱讀這個。你看到什麼啓發嗎? – Jeff