Glassfish DAS OutOfMemory с обща използвана памет под максималния размер на паметта

Изпълнявам голямо корпоративно приложение в клъстерна конфигурация на Glassfish V2.1 с 6 екземпляра (SLES 10 SP4, 64-битова Suse Linux машина с 19 Gb RAM) и DAS машината server.log показва някои „java.lang.OutOfMemoryError: Java heap space" грешки. Докладът за използване на купчина от jvm.log на DAS показва:

Heap
 PSYoungGen      total 103488K, used 99840K [0x00002aab237c0000, 0x00002aab2a270000, 0x00002aab4e260000)
  eden space 99840K, 100% used [0x00002aab237c0000,0x00002aab29940000,0x00002aab29940000)
  from space 3648K, 0% used [0x00002aab29940000,0x00002aab29940000,0x00002aab29cd0000)
  to   space 4672K, 0% used [0x00002aab29de0000,0x00002aab29de0000,0x00002aab2a270000)
 PSOldGen        total 1398144K, used 1398143K [0x00002aaace260000, 0x00002aab237c0000, 0x00002aab237c0000)
  object space 1398144K, 99% used [0x00002aaace260000,0x00002aab237bfe70,0x00002aab237c0000)
 PSPermGen       total 107200K, used 106931K [0x00002aaaae260000, 0x00002aaab4b10000, 0x00002aaace260000)
  object space 107200K, 99% used [0x00002aaaae260000,0x00002aaab4accd98,0x00002aaab4b10000)

От горното получаваме общо хийп пространство от 1,6 Gb (103488 + 1398144 + 107200 = 1608832 ~ 1,6 Gb), въпреки че максималното разрешено хийп пространство е зададено на 2 Gb (-XX:MaxPermSize=512m -Xmx2048m). Въпросът ми тогава е: защо JVM не увеличава размера на купчината, преди да изведе OOM грешки? Как можем да тълкуваме горния отчет за купчина? Пуснах инструмента MAT на двоичен хъп файл и получих 2 заподозрени теча:

Problem suspect #1

One instance of "com.sun.jmx.mbeanserver.JmxMBeanServer" loaded by "<system class loader>" occupies 522,351,680 (34.12%) bytes. The instance is referenced by org.jvnet.glassfish.comms.admin.management.extensions.config.OverloadProtectionServiceConfigImpl @ 0x2aaacfe74ed0 , loaded by "com.sun.appserv.server.util.ASURLClassLoader @ 0x2aaace7fc630". The memory is accumulated in one instance of "java.util.HashMap$Entry[]" loaded by "<system class loader>".

Keywords
java.util.HashMap$Entry[]
com.sun.appserv.server.util.ASURLClassLoader @ 0x2aaace7fc630
com.sun.jmx.mbeanserver.JmxMBeanServer

Problem suspect #2

140,421 instances of "net.jxta.impl.endpoint.tcp.TcpMessenger", loaded by "com.sun.appserv.server.util.ASURLClassLoader @ 0x2aaace7fc630" occupy 735,809,464 (48.07%) bytes. These instances are referenced from one instance of "java.util.TimerTask[]", loaded by "<system class loader>"

Keywords
java.util.TimerTask[]
com.sun.appserv.server.util.ASURLClassLoader @ 0x2aaace7fc630
net.jxta.impl.endpoint.tcp.TcpMessenger

За съжаление грешката възникна преди няколко седмици и оттогава машината беше рестартирана, така че може да съм загубил част от контекстната информация. Търся съвети или обяснения и се опитвам да предотвратя тези грешки. Благодаря предварително за всяка помощ.

наздраве

/Сам


person Sam Carter    schedule 16.03.2012    source източник
comment
Къде е действителната OOM грешка? По-скоро изглежда, че сте изчерпали permgen, отколкото heap mem.   -  person Preston    schedule 17.03.2012


Отговори (1)


Въпросът ми тогава е: защо JVM не увеличава размера на купчината, преди да изведе OOM грешки?

С JVM-опциите, които сте задали (-Xmx2048m), максималното пространство на купчина ще бъде 2G, точно така, но не сте задали опцията за първоначално пространство на купчина -Xms1024.
Тази опция ще укаже на JVM да предостави на сървъра първоначално 1024MB пространство в купчина, вместо да го увеличава бавно, когато е необходимо.

Това може да ви попречи да получите OOM грешки, защото понякога JVM не забелязва някои промени в паметта поради GC.

Разгледайте това, за да настроите вашия сървър за приложения .

Относно вашите MemLeaks:
Трудно е да се каже дали това са истински течове на памет или просто някои сървърни класове.
За да проверите това, можете да задействате дъмп на паметта и да го анализирате, напр. MemoryAnalyser

Надявам се това да помогне, забавлявайте се!

person SimonSez    schedule 16.03.2012
comment
Взех си под внимание и този параметър за първоначален размер на купчината (-Xms) определено трябва да бъде зададен (на максимална стойност на размера на купчината, IMHO). Коментарът, който направихте: защото понякога JVM не забелязва някои промени в паметта поради GC, ме тревожи. Имате ли някаква конкретна справка за грешка, която мога да разгледам? Също така забелязах, че опциите за JVM, свързани с GC и heap, са зададени и настроени за екземплярите на клъстера, но само частично в конфигурацията на сървъра (DAS). Благодаря за проницателния отговор. - person Sam Carter; 19.03.2012
comment
Ваше право, стойността -Xms трябва да бъде зададена на стойност -Xmx. Съжалявам, засега нямам препратки под ръка (само програма за проследяване на грешки за това, че GC не се изпълнява след многократно повторно разполагане), но мога да препоръчам това и тази статия за настройката, особено за събирането на отпадъци. Те ми помогнаха да реша това в моята среда! наздраве! - person SimonSez; 19.03.2012