Ограничение времени сбора мусора Java

91
7

Ситуация


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


Иногда поиск правильного ответа занимает почти 2 секунды, а иногда это всего лишь несколько миллисекунд. Проблема заключается в том, что сбор мусора происходит в одном из более длинных вычислений (который также выделяет много объектов) прямо к концу двух секунд, и, таким образом, ответ отправляется слишком поздно, и я получаю дисквалификацию.


Используя verbose gc output, я определил, что gc обычно занимает около 0,6 с, хотя я пытался его ограничить. Я также попытался вызвать System.gc() для более коротких вычислений (поскольку я уверен, что у меня около 1,8, где мне не нужно ничего делать), но это заняло 1-3 с, что тоже небезопасно.


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


функции


Я знаю, что программа всегда будет работать на том же компьютере, где доступны эти ресурсы:


Мои текущие параметры jvm:


java -Dfile.encoding=UTF-8 \
-XX:MaxGCPauseMillis=200 \
-XX:GCPauseIntervalMillis=2050 \
-XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled \
-XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 \
-XX:+ScavengeBeforeFullGC -XX:+CMSScavengeBeforeRemark \
-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps

Идеи


    Могу ли я каким-то образом сказать gc, что теперь он должен собирать мусор, но только около 1,5 секунд?
    Существует ли эквивалент System.gc(), который работает только с молодыми объектами и не проверяет поколение поколений?
    Можно ли оптимизировать параметры jvm для достижения лучших результатов?

спросил(а) 2021-01-19T14:55:24+03:00 9 месяцев, 1 неделя назад
1
Решение
79

Здесь вы можете попытаться уменьшить паузы:

    Попробуйте сборщик G1 вместо CMS
    Используйте более реалистичные цели GC. Текущие цели позволяют 200 мс времени остановки в мире GC каждые 2 секунды. Увеличьте MaxGCPauseMillis и/или уменьшите GCPauseIntervalMillis.
    Добавьте еще одно ядро, чтобы JVM смог GC параллельно с вашим приложением.
    Уменьшить CMSInitiatingOccupancyFraction, чтобы GC запускал потоки GC GC, когда куча менее заполнена.
    Уменьшите скорость, с которой ваше приложение создает мусор.
    Настройте свои алгоритмы приложений, чтобы больше свободного времени для фона GC (на одном ядре).

ответил(а) 2021-01-19T14:55:24+03:00 9 месяцев, 1 неделя назад
46

После большого количества экспериментов я нашел нужные мне флаги и хочу поделиться этими знаниями сейчас:


    -XX:+UseConcMarkSweepGC - после сравнения результатов журналов G1 и CMS для моей утилиты, я определил, что время паузы CMS ниже, кроме того, оно поддерживает однопоточные коллекции
    -XX:+ExplicitGCInvokesConcurrent При вызове System.gc() не будет вызываться полный GC, а стандартный.
    -XX:NewRatio=1 отношение размеров старого поколения к молодому поколению, это самое низкое значение, так как у меня очень мало долгоживущих объектов.
    -mx800m -ms800m уменьшает и исправляет размер памяти, поэтому коллекции будут происходить чаще и меньше времени. Пропускная способность для реагирования.
    -XX:-UseParNewGC Отключает распараллеливание для сбора молодого поколения. Это был разбойник и сократил время остановки в мире от 0.2-0.5s до 0.02-0.2s, так как у меня есть только одно ядро. (Объединение этого с CMS устарело и может быть удалено в новых версиях Java)

Используя эти параметры, я мог уменьшить время паузы GC от 0,4 с до 3 с до менее 0,2 с. И для полноты эти флаги были наиболее полезными для отладки:

-XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -XX:+PrintTenuringDistribution

Не забывайте, что они оптимизированы для очень специфических требований: одно одно ядро ​​доступно, много молодого мусора, старые коллекции, очень низкие остановки-паузы


Это небольшой чит-лист, который я могу порекомендовать для дальнейшего чтения: http://blog.ragozin.info/2016/10/hotspot-jvm-garbage-collection-options.html

ответил(а) 2021-01-19T14:55:24+03:00 9 месяцев, 1 неделя назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема