Я запускаю приложение, которое создает и забывает большое количество объектов, количество давно существующих объектов растет медленно, но это очень мало по сравнению с недолговечными объектами.Это настольное приложение с высокими требованиями к доступности, его нужно включать 24 часа в сутки.Большая часть работы выполняется в одном потоке, этот поток будет использовать только тот процессор, который он может достать.
В прошлом мы видели следующее при большой нагрузке: используемое пространство кучи медленно увеличивается каксборщик мусора собирает меньше, чем объем вновь выделенной памяти, размер используемой кучи медленно увеличивается и в конечном итоге приближается к указанной максимальной куче.В этот момент сборщик мусора сильно включится и начнет использовать огромное количество ресурсов, чтобы предотвратить превышение максимального размера кучи.Это замедляет работу приложения (легко в 10 раз медленнее), и в этот момент GC в большинстве случаев удастся очистить мусор через несколько минут или потерпит неудачу и выдаст OutOfMemoryException
, оба они не совсем приемлемы.
Используемое аппаратное обеспечение представляет собой четырехъядерный процессор с не менее 4 ГБ памяти под управлением 64-разрядной ОС Linux, и все это мы можем использовать при необходимости.В настоящее время приложение интенсивно использует одно ядро, которое большую часть времени использует одно ядро / поток.Другие ядра в основном простаивают и могут быть использованы для сборки мусора.
У меня такое чувство, что сборщик мусора должен собирать более агрессивно на ранней стадии, задолго до того, как ему не хватит памяти.В нашем приложении нет проблем с пропускной способностью, требования к малому времени паузы немного важнее, чем пропускная способность, но гораздо менее важны, чем не достижение максимального размера кучи.Это допустимо, если один занятый поток работает только на 75% от текущей скорости, если это означает, что сборщик мусора может не отставать от создания.Короче говоря, устойчивое снижение производительности лучше, чем внезапное падение, которое мы наблюдаем сейчас.
Я прочитал Java SE 6 HotSpot [tm] Настройка сборки мусора виртуальной машины , что означает, что я хорошо понимаю параметры, однако мне все еще трудно выбрать правильные настройки в качестве моихтребования немного отличаются от того, что обсуждается в статье.
В настоящее время я использую ParallelGC с опцией -XX:GCTimeRatio=4
.Это работает немного лучше, чем настройка по умолчанию для соотношения времени, но у меня есть ощущение, что GC разрешено работать больше с этой настройкой, чем делает.
Для мониторинга я использую в основном jconsole и jvisualvm.
Я хотел бы знать, какие параметры сборки мусора вы рекомендуете для вышеуказанной ситуации.Кроме того, какие выходные данные отладки GC я могу посмотреть, чтобы лучше понять горлышко бутылки.
РЕДАКТИРОВАТЬ: Я понимаю, что очень хороший вариант здесь - создать меньше мусора, это то, что мы действительно рассматриваемТем не менее, я хотел бы знать, как мы можем решить эту проблему с помощью настройки GC, поскольку это то, что мы можем сделать гораздо проще и быстрее развернуть, чем изменять большие объемы исходного кода.Также я запустил различные профилировщики памяти, и я понимаю, что мусор используется, и там я знаю, что он состоит из объектов, которые могут быть собраны.
Я использую:
java version "1.6.0_27-ea"
Java(TM) SE Runtime Environment (build 1.6.0_27-ea-b03)
Java HotSpot(TM) 64-Bit Server VM (build 20.2-b03, mixed mode)
С параметрами JVM:
-Xmx1024M and -XX:GCTimeRatio=4
Редактировать в ответ на комментарии Мэтса: Большая часть памяти (и ЦП)) идет к созданию объектов, которые представляют текущую ситуацию.Некоторые из них будут сразу же отброшены, так как ситуация быстро изменится, другие будут иметь средний срок службы, если в течение некоторого времени не будет никаких обновлений.