Тюнинг JVM и GC - теория без полного GC - PullRequest
13 голосов
/ 03 июня 2011

У меня есть крупномасштабное приложение с двумя типами объектов: долгоживущими (кеш) и недолговечными (запрос-процесс-ответ). Теоретически, с этим типом приложения, я думаю, что можно настроить пространство Юнга против Старого, поэтому потребление Старого пространства остается постоянным, что приводит к отсутствию полного GC.

Я изменил параметры newSize-maxNewSize, но Старая куча продолжает расти до полной GC. После каждого полного GC потребление снижается до 20% (кэш-память занимает 20%). Почему-то мои объекты попадают в Старое пространство. У меня есть два подозреваемых, почему переехали в Старое пространство:

  • Согласно этой статье: http://chaoticjava.com/posts/gc-tips-and-memory-leaks/ сказано, что если у вас выделены большие объекты, они идут прямо в старое пространство. Это правда, и если это так, есть ли параметр JVM Option, который может установить порог размера объекта для пространства Юнга?

  • Если я правильно понял процесс, объекты переключаются между разделами выживания «До-От» до того, как перемещаются в раздел «Старый». Есть ли параметр, который может установить, сколько переключений между «Кому» и «От» нужно сделать, прежде чем перейти в старое пространство?

Есть еще советы?

Спасибо, Амар

Ответы [ 4 ]

5 голосов
/ 03 июня 2011

Вы уверены, что рост старого поколения это просто не кешированные объекты?Если ваш кеш не исправлен и никогда не изменяется, вы будете постоянно добавлять к нему.Поскольку объекты, которые попали в старое поколение, истекают из этого кэша, они будут оставаться в памяти до следующего полного сбора мусора.длинные паузы от полных сборов.Это займет немного настройки и может варьироваться в зависимости от приложения.Вот что мы используем для запуска 24 ГБ 64-битной JVM с паузой GC в секунду, обслуживающей более 100 запросов страниц в секунду с большими кэшами:

-Xms24g -Xmx24g -XX:+UseCompressedOops -XX:NewRatio=4 -XX:SurvivorRatio=8    
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+DisableExplicitGC  
-XX:+UseCMSInitiatingOccupancyOnly -XX:+CMSClassUnloadingEnabled  
-XX:+CMSScavengeBeforeRemark -XX:CMSInitiatingOccupancyFraction=68
5 голосов
/ 03 июня 2011

Звучит так, будто места для выживших недостаточно велики.Вы должны сделать их достаточно большими, чтобы не нужно было собирать объекты.Объект переключается в пространство выжившего только один раз.

Если вы выделяете большие объекты, можете ли вы использовать для них Пул объектов, избегая необходимости их GC.Рассматривали ли вы возможность использования пула объектов для данных запроса / процесса / ответа?например, простым является использование ThreadLocal.

Вы пробовали сборщик G1, предназначенный для постепенного сбора всей вашей памяти и уменьшения большого попадания полного GC.

2 голосов
/ 03 июня 2011

Есть ли параметр, который может установить, сколько переключений между «Кому» и «От» должно быть выполнено до перехода в «Старое пространство»?

Да, -XX:MaxTenuringThreshold

ЭтоПараметр switch определяет, сколько раз объекты переходят между пространствами Survivor «От» и «До», прежде чем перейти в старшее поколение.Наибольшее значение 15 для Java 6 и 31 для более ранних JDK. Значение по умолчанию 15 для параллельного коллектора и 4 для сборщиков CMS .

Из документов GV Sun JVM,

Использовать -XX: MaxTenuringThreshold =0, чтобы немедленно переместить объект, который сохранился в коллекции молодого поколения, в штатное поколение.

Если вы хотите сделать обратное, если вы не установите это значение, оно будет по умолчанию., чего вполне достаточно, чтобы решить, нужно ли объекту переходить в «Старый» - при условии , как говорит @Peter, выжившие достаточно велики, чтобы содержать эти объекты.

Что установлено в SurvivorRatio на?А какая у тебя общая куча?

0 голосов
/ 05 февраля 2014

Характеристики времени жизни объекта здесь играют решающую роль. Важными ручками настройки являются размер места выжившего, порог владения и размер молодого поколения. Стратегически мы хотим, чтобы объекты умирали молодыми, поэтому, если будет достаточно промежутка между второстепенными коллекциями, многие объекты умрут в молодом поколении. Кроме того, мы можем настроить порог владения таким образом, чтобы объекты оставались в пространстве оставшихся в живых для желаемого количества коллекций.

Поскольку мы сохраняем большое количество живых объектов в пространстве выживших и продолжаем копировать их из одного пространства в другое для ряда второстепенных ГХ, это увеличивает стоимость второстепенных ГХ.

Сохранение большого молодого поколения естественным образом увеличивает разрыв между последовательными второстепенными коллекциями и дает больше времени для смерти объектов.

Можно достичь правильного баланса, экспериментируя с этими переменными, чтобы сократить продвижение объектов до старого поколения с учетом допустимых пауз для молодого поколения

...