Сборка мусора Java G1 в производстве - PullRequest
89 голосов
/ 12 февраля 2010

Поскольку Java 7 по умолчанию будет использовать новую сборку мусора G1, сможет ли Java обрабатывать кучу на порядок больше без предполагаемого «разрушительного» времени приостановки GC? Кто-нибудь на самом деле внедрил G1 в производство, каков был ваш опыт?

Чтобы быть справедливым, единственный раз, когда я видел действительно длинные паузы GC, это очень большие кучи, гораздо больше, чем рабочая станция. Уточнить мой вопрос; откроет ли G1 шлюз в сотни ГБ? TB

Ответы [ 16 ]

58 голосов
/ 19 октября 2010

Я тестировал его с тяжелым приложением: 60-70 ГБ выделено для кучи, и 20-50 ГБ используется в любое время. С такими приложениями не стоит говорить, что ваш пробег может отличаться. Я использую JDK 1.6_22 в Linux. Незначительные версии важны - примерно до 1.6_20 в G1 были ошибки, которые вызывали случайные исключения NullPointerException.

Я обнаружил, что он очень хорошо держит цель паузы, которую вы ставите большую часть времени. По умолчанию используется пауза в 100 мс (0,1 секунды), и я сказал ей сделать это вдвое меньше (-XX: MaxGCPauseMillis = 50). Тем не менее, как только у него становится мало памяти, он паникует и выполняет полную сборку мусора «остановить мир». С 65 ГБ это занимает от 30 секунд до 2 минут. (Количество процессоров, вероятно, не имеет значения; возможно, оно ограничено скоростью шины.)

По сравнению с CMS (которая не является GC-сервером по умолчанию, но должна использоваться для веб-серверов и других приложений реального времени), типичные паузы гораздо более предсказуемы и их можно сделать намного короче. До сих пор мне больше повезло с CMS для огромных пауз, но это может быть случайным; Я вижу их только несколько раз каждые 24 часа. Я не уверен, какой из них будет более подходящим в моей производственной среде на данный момент, но, вероятно, G1. Если Oracle продолжит настраивать его, я подозреваю, что в конечном итоге победит G1.

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

34 голосов
/ 12 февраля 2010

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

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

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

EDIT:

при перечитывании мне пришло в голову, что я ежедневно использую Java - Eclipse, Azureus и приложения, которые я разрабатываю, и это было ДОЛГОЕ ВРЕМЯ с тех пор, как я увидел паузу. Не существенная пауза, но я имею в виду любую паузу вообще.

Я видел паузы, когда я щелкаю правой кнопкой мыши на проводнике Windows или (иногда), когда я подключаю определенное оборудование USB, но с Java - нет вообще.

GC все еще проблема с кем-либо?

14 голосов
/ 15 декабря 2010

Хотя я не тестировал G1 в производстве, я подумал, что прокомментирую, что GC уже проблематичны для случаев без "огромных" куч. В частности, GC может серьезно повлиять на услуги, скажем, на 2 или 4 гигабайта. ГХ молодого поколения обычно не представляют проблем, поскольку они заканчиваются за однозначные миллисекунды (или самое большее двузначные). Но коллекции старого поколения гораздо более проблематичны, так как они занимают несколько секунд с размерами старого поколения от 1 гига и выше.

Теперь: теоретически CMS может сильно помочь, поскольку он может выполнять большую часть своей работы одновременно. Однако со временем будут случаи, когда он не сможет этого сделать и вынужден будет прибегнуть к помощи коллекции «Остановить мир». И когда это произойдет (скажем, через 1 час - не часто, но все же слишком часто), хорошо, держитесь за свои чертовы шляпы. Это может занять минуту или больше. Это особенно проблематично для служб, которые пытаются ограничить максимальную задержку; вместо того, чтобы потребовать, скажем, 25 миллисекунд для обработки запроса, теперь требуется десять секунд или больше. Чтобы добавить травму к оскорблению, клиенты будут часто тайм-аут запроса и повторять попытки, что приведет к дальнейшим проблемам (иначе как «дерьмо буря»).

Это одна из областей, где G1 надеялся сильно помочь. Я работал в большой компании, которая предлагает облачные сервисы для хранения и отправки сообщений; и мы не могли использовать CMS, так как, хотя большую часть времени она работала лучше, чем параллельные, у нее были эти провалы. Так около часа все было хорошо; и затем что-то попало в вентилятор ... и поскольку сервис основывался на кластерах, когда один узел попадал в беду, другие обычно следовали (поскольку тайм-ауты, вызванные GC, приводят к тому, что другие узлы полагают, что узел вышел из строя, что приводит к перенаправлению).

Я не думаю, что GC является большой проблемой для приложений, и, возможно, даже на некластеризованные сервисы это влияет реже. Но все больше и больше систем кластеризуются (особенно благодаря хранилищам данных NoSQL), и размеры кучи растут. GC OldGen суперлинейно связаны с размером кучи (это означает, что удвоение размера кучи более чем удваивает время GC, при условии, что размер набора данных в реальном времени также удваивается).

13 голосов
/ 11 января 2012

Технический директор Azul, Гил Тене (Gil Tene), имеет хороший обзор проблем, связанных с сборкой мусора, и обзор различных решений в его Понимании Java-сборки мусора и том, что вы можете с этим сделать презентация, и есть дополнительная подробно в этой статье: http://www.infoq.com/articles/azul_gc_in_detail.

Сборщик мусора Azul C4 в нашей Zing JVM является параллельным и параллельным и использует один и тот же механизм GC для нового и старого поколений, работая одновременно и уплотняя в обоих случаях. Самое главное, что у C4 нет возврата к остановке. Все уплотнения выполняются одновременно с запущенным приложением. У нас есть клиенты, работающие очень большими (сотни ГБайт) с худшим временем задержки GC <10 мсек, а в зависимости от приложения часто менее 1-2 мсек. </p>

Проблема с CMS и G1 заключается в том, что в какой-то момент память кучи Java должна быть сжата, и оба этих сборщика мусора останавливают мир / STW (то есть приостанавливают приложение) для выполнения сжатия. Таким образом, хотя CMS и G1 могут выдвигать паузы STW, они не устраняют их. Однако C4 от Azul полностью исключает паузы STW, и поэтому у Zing такие низкие GC-паузы даже для гигантских размеров кучи.

И чтобы исправить утверждение, сделанное в предыдущем ответе, Zing не требует никаких изменений в операционной системе. Он работает так же, как и любая другая JVM в неизмененных дистрибутивах Linux.

12 голосов
/ 20 февраля 2013

Мы уже используем G1GC почти два года назад. Это прекрасно работает в нашей системе обработки критически важных транзакций, и она оказалась отличной поддержкой с высокой пропускной способностью, низкими паузами, параллелизмом и оптимизированным управлением тяжелой памятью.

Мы используем следующие настройки JVM:

-server -Xms512m -Xmx3076m -XX:NewRatio=50 -XX:+HeapDumpOnOutOfMemoryError -XX:+UseG1GC -XX:+AggressiveOpts -XX:+UnlockExperimentalVMOptions -XX:MaxGCPauseMillis=400 -XX:GCPauseIntervalMillis=8000 -XX:+PrintGCTimeStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime

Обновлено

-d64 -server -Xss4m -Xms1024m -Xmx4096m -XX:NewRatio=50 -XX:+UseG1GC -XX:+UnlockExperimentalVMOptions -XX:+HeapDumpOnOutOfMemoryError -XX:-DisableExplicitGC -XX:+AggressiveOpts -Xnoclassgc -XX:+UseNUMA -XX:+UseFastAccessorMethods -XX:ReservedCodeCacheSize=48m -XX:+UseStringCache -XX:+UseStringDeduplication -XX:MaxGCPauseMillis=400 -XX:GCPauseIntervalMillis=8000
8 голосов
/ 12 февраля 2010

Коллектор G1 уменьшает влияние полных коллекций. Если у вас есть приложение, в котором вы уже сократили потребность в полных коллекциях, то коллектор с разверткой карты Concurrent столь же хорош, и, по моему опыту, сокращает время сбора незначительных сборов.

5 голосов
/ 01 июня 2012

Похоже, что G1, запускающая JDK7u4, наконец-то официально поддерживается, см. RN для JDK7u4 http://www.oracle.com/technetwork/java/javase/7u4-relnotes-1575007.html.

По результатам нашего тестирования для больших JVM, настроенная CMS по-прежнему работает лучше, чем G1, но, думаю, она будет расти лучше.

4 голосов
/ 13 декабря 2015

Недавно меня перевели из

CMS для G1GC с кучей 4G и 8-ядерным процессором на серверах с JDK 1.7.45 .

(JDK 1.8.x G1GC предпочтительнее, чем 1.7, но из-за некоторых ограничений я должен придерживаться версии 1.7.45)

Я настроил ниже основных параметров и оставил все остальные параметры в значения по умолчанию.

-XX:G1HeapRegionSize=n, XX:MaxGCPauseMillis=m, -XX:ParallelGCThreads=n, 
-XX:ConcGCThreads=n apart from -Xms and -Xmx

Если вы хотите точно настроить эти параметры, взгляните на эту статью oracle .

Ключевые наблюдения:

  1. Использование памяти соответствует G1GC в отличие от максимумов и минимумов с CMS
  2. Макс. Время паузы ГХ меньше по сравнению с CMS
  3. Время, затрачиваемое на сборку мусора, немного больше в G1GC по сравнению с CMS.
  4. Количество крупных коллекций практически ничтожно по сравнению с CMS
  5. Количество второстепенных коллекций выше по сравнению с CMS

Но все же я рад, что время паузы Max GC меньше, чем у CMS. Я установил максимальное время паузы GC как 1,5 секунды , и это значение еще не пересечено.

Вопрос по теме SE:

Сборка мусора Java 7 (JDK 7) и документация по G1

4 голосов
/ 03 октября 2013

Я только что реализовал сборщик мусора G1 в нашем проекте Terracotta Big Memory. Работая над разными типами коллекторов, G1 дал нам лучшие результаты с временем отклика менее 600 мс.

Вы можете найти результаты теста (всего 26) здесь

Надеюсь, это поможет.

4 голосов
/ 03 ноября 2011

G1 GC должен работать лучше. Но если установить -XX: MaxGCPauseMillis слишком агрессивно, мусор будет собираться слишком медленно. И именно поэтому полный GC сработал в примере Дэвида Леппика.

...