Превышен предел накладных расходов GC

93

Какое время выборки использует JVM для выдачи 'java.lang.OutOfMemoryError: превышен предел накладных расходов GC'? Я знаю, что вы можете контролировать 98% и 2% с помощью параметров GCTimeLimit и GCHeapFreeLimit, но каково время выборки?

PRK
источник

Ответы:

82

Из Java SE 6 HotSpot [tm] Настройка сборки мусора виртуальной машины

продолжение

Чрезмерное время сборки мусора и ошибка OutOfMemoryError

Параллельный сборщик выдаст OutOfMemoryError, если на сборку мусора тратится слишком много времени: если на сборку мусора уходит более 98% общего времени и восстанавливается менее 2% кучи, будет выброшено OutOfMemoryError. Эта функция предназначена для предотвращения запуска приложений в течение длительного периода времени при незначительном прогрессе или отсутствии прогресса из-за слишком маленькой кучи. При необходимости эту функцию можно отключить, добавив параметр -XX: -UseGCOverheadLimit в командную строку.

Политика такая же, как и в параллельном сборщике, за исключением того, что время, потраченное на выполнение параллельных сборов, не учитывается в 98% -м ограничении времени. Другими словами, только сборы, выполненные, когда приложение остановлено, засчитываются в чрезмерное время сборки мусора. Такие коллекции обычно возникают из-за сбоя в параллельном режиме или явного запроса на сбор (например, вызов System.gc ()).

в сочетании с проходом ниже

Одно из наиболее часто встречающихся применений явной сборки мусора происходит с распределенной сборкой мусора (DGC) RMI. Приложения, использующие RMI, относятся к объектам в других виртуальных машинах. Сбор мусора в этих распределенных приложениях невозможно без периодической сборки локальной кучи, поэтому RMI периодически принудительно выполняет полную сборку. Частоту этих коллекций можно контролировать с помощью свойств. Например,

java -Dsun.rmi.dgc.client.gcInterval=3600000

-Dsun.rmi.dgc.server.gcInterval=3600000 указывает явный сбор один раз в час вместо стандартной скорости один раз в минуту. Однако из-за этого может потребоваться гораздо больше времени для восстановления некоторых объектов. Эти свойства могут быть установлены такими высокими, как Long.MAX_VALUE, чтобы время между явными сборами было фактически бесконечным, если нет желания устанавливать верхнюю границу своевременности активности DGC.

Кажется, подразумевается, что период оценки для определения 98% составляет одну минуту, но его можно настроить на JVM Sun с правильным определением.

Конечно, возможны и другие интерпретации.

Эдвин Бак
источник
5
Распределенная сборка мусора RMI не связана с обычной сборкой мусора. Поэтому я не понимаю, как вы можете сделать вывод о том, что вы только что сделали.
Stephen C
2
Вывод не идеален и даже не верен, поэтому вместо «подразумевается» используется «кажется, подразумевает». Если вы согласны с наблюдением, что если люди в Sun использовали одну минуту для определения интервала сборки мусора для RMI, то время сборки в параллельной сборке накапливается, рассчитывается только при остановке основной программы и делает небольшой прыжок веры , то хорошие шансы, что 98% будет собрано за одну минуту. Это магическое число, но одна минута - это магическое число, которое часто используется по сравнению с 3,5 минутами.
Эдвин Бак
@StephenC, вы имеете в виду, что даже если мы установим, -XX:+DisableExplicitGC это не повлияет на конфигурацию, связанную с RMI, и система будет вызывать gc с частотой, заданной параметром-Dsun.rmi.dgc.server.gcInterval
Steephen
1
@Steephen - Нет. Я не это говорю. Я говорю об этом утверждении: «Кажется, подразумевается, что период оценки для определения 98% составляет одну минуту ...» . И обратите внимание, что Эдвин согласен с тем, что вывод «несовершенный». Вывод основан на предположении, что люди из Sun, которые реализовали RMI (& DGC), были в тесном контакте с людьми, которые реализовали механизм ограничения накладных расходов GC. Я подозреваю, что эти два события на самом деле произошли в разное время. Обратите внимание, что это -Dsun.rmi.dgc.server.gcIntervalсвойство существует с Java 1.2.
Stephen C
1
В любом случае, лучший подход к поиску настоящего ответа на этот вопрос - посмотреть исходный код OpenJDK.
Stephen C