Java GC периодически входит в несколько полных циклов GC - PullRequest
4 голосов
/ 04 января 2011

Окружающая среда:

sun JDK 1.6.0_16

vm settings:
-XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -Xms1024 -Xmx1024M -XX:MaxNewSize=448m -XX:NewSize=448m -XX:SurvivorRatio=4(6 also checked) -XX:MaxPermSize=128M

OS: windows server 2003

processor: 4 cores of INTEL XEON 5130,  2000 Hz

описание моего приложения: высокая интенсивность одновременных (используется параллельный java 5) операций, выполняемых каждый раз коммитом к оракулу. около 20-30 потоков работают без остановок, выполняя задачи.

приложение запускается в веб-контейнере JBOSS.

Мой ГХ начинает работать нормально, я вижу много маленьких ГХ, и все это время процессор показывает хорошую нагрузку, как и все 4 ядра, загруженные на 40-50%, график процессора стабилен.

Затем, после 1 минуты хорошей работы, процессор начинает падать до 0% на 2 ядрах из 4, график становится нестабильным, идет вверх и вниз («зубья»). Я вижу, что мои потоки работают медленнее (у меня есть мониторинг), я вижу, что GC начинает производить много FULL GC в течение этого времени, и в следующие 4-5 минут эта ситуация остается такой, как есть, затем в течение короткого периода времени, например, 1 минуты. , он возвращается к нормальной ситуации, но вскоре все это повторяется.

Вопрос: Почему у меня так часто бывает полный GC ??? Как это предотвратить?

Я играл с SurvivorRatio - не помогает.

Я заметил, что приложение ведет себя нормально, пока не произойдет первый полный сборщик мусора, пока у меня достаточно памяти. Тогда он работает плохо.

мой журнал GC: * ​​1020 *

  1. начинается хорошо
  2. затем длительный период ПОЛНЫХ ГК (многие из них)

1027.861: [GC 942200K->623526K(991232K), 0.0887588 secs]
1029.333: [GC 803279K(991232K), 0.0927470 secs]
1030.551: [GC 967485K->625549K(991232K), 0.0823024 secs]
1030.634: [GC 625957K(991232K), 0.0763656 secs]
1033.126: [GC 969613K->632963K(991232K), 0.0850611 secs]
1033.281: [GC 649899K(991232K), 0.0378358 secs]
1035.910: [GC 813948K(991232K), 0.3540375 secs]
1037.994: [GC 967729K->637198K(991232K), 0.0826042 secs]
1038.435: [GC 710309K(991232K), 0.1370703 secs]
1039.665: [GC 980494K->972462K(991232K), 0.6398589 secs]
1040.306: [Full GC 972462K->619643K(991232K), 3.7780597 secs]
1044.093: [GC 620103K(991232K), 0.0695221 secs]
1047.870: [Full GC 991231K->626514K(991232K), 3.8732457 secs]
1053.739: [GC 942140K(991232K), 0.5410483 secs]
1056.343: [Full GC 991232K->634157K(991232K), 3.9071443 secs]
1061.257: [GC 786274K(991232K), 0.3106603 secs]
1065.229: [Full GC 991232K->641617K(991232K), 3.9565638 secs]
1071.192: [GC 945999K(991232K), 0.5401515 secs]
1073.793: [Full GC 991231K->648045K(991232K), 3.9627814 secs]
1079.754: [GC 936641K(991232K), 0.5321197 secs]

Ответы [ 2 ]

3 голосов
/ 04 января 2011

Из последних двух строк вашего журнала (до того, как вы отредактировали свой вопрос):

397.245: [Full GC 660160K->443379K(660160K), 2.7433121 secs]
401.793: [Full GC 660160K->446464K(660160K), 2.7697340 secs]

Вы определенно достигли предела памяти, который составляет 660160K.Этот предел равен общему доступному пространству, не считая места в постоянном поколении, которое представляет собой общую кучу минус одно пространство выживших. ( Ref )

Каждые четыре секунды вы создаете ~ 220M новых объектов gc'able, общее потребление памяти увеличивается со скоростью 1 МБ / с.Поэтому через некоторое время JVM не будет делать ничего, кроме Full GC, пока не будет исчерпано пространство кучи.

В этом сценарии я сильно сомневаюсь, что настройка памяти поможет в течение длительного времени, просто потому, что вы нажметепредел уже через 6 минут.

Похоже, вам нужно искать утечки памяти или сохраненную ссылку на большие неиспользуемые объекты (наборы результатов, объекты DOM, ...)

С новыми значениями: та же ситуация,Вы по-прежнему достигаете того же верхнего предела памяти, просто это происходит через несколько минут, потому что вы выделили больше памяти.Действительно пахнет как утечка памяти.Вы по-прежнему производите контент gc'able со скоростью ~ 60 МБ / с.

2 голосов
/ 04 января 2011

Это не похоже на случай утечки памяти;вполне возможно, что вся эта память на самом деле используется используемой JVM, что может объяснить частые полные сборщики мусора.Есть ли шанс, что вы можете создать несколько процессов?т.е. вместо одного процесса, имеющего 20-30 потоков, с 5 процессами, выполняющими по 4-5 потоков каждый?параметры на месте?Наблюдали ли вы какой-либо значительный выигрыш в производительности, имея эти вещи там?Мой первый подход при настройке любого приложения - запустить его с минимальными настройками на JVM и вносить изменения только в том случае, если мои новые добавленные параметры do влияют на текущую ситуацию.*

...