Java G1 сборка мусора в производстве

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

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

16 ответов


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

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

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

EDIT:

при перечитывании мне пришло в голову, что я использую Java daily--Eclipse, Azureus и приложения, которые я разрабатываю, и прошло много времени с тех пор, как я видел паузу. Не многозначительная пауза, но я имею в виду любую паузу вообще.

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

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


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

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

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

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


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

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

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

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


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

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

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

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


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

мы используем следующие настройки 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

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


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

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


CMS может привести к медленному снижению производительности, даже если вы используете его без накопления напряженных объектов. Это связано с фрагментацией памяти, которую G1 предположительно избегает.

миф о G1, доступный только с платной поддержкой, - это просто миф. Sun и теперь Oracle прояснили это на странице JDK.


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


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

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

надеюсь, что это помогает.


недавно я был перемещен из

CMS для G1GC с 4G heap & 8 core процессором на серверах с 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 в отличие от high & lows с CMS
  2. максимальное время паузы GC меньше по сравнению с CMS
  3. время, проведенное в сборе мусора, немного выше в G1GC по сравнению с CMS.
  4. количество основных коллекций почти незначительно по сравнению с CMS
  5. количество незначительных коллекций на более высоком конце по сравнению с CMS

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

связанный вопрос SE:

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


недавно я перенес часть Twicsy на новый сервер с ОЗУ 128GB и решил использовать 1.7. Я начал использовать все те же настройки памяти, что и с 1.6 (у меня есть несколько экземпляров, работающих с различными вещами, от 500 Мб кучи до 15 ГБ, а теперь новый с 40 ГБ), и это не сработало хорошо. 1.7, кажется, использует больше кучи, чем 1.6, и я испытал много проблем в течение первых нескольких дней. К счастью, у меня было много ОЗУ для работы, и я столкнулся с ОЗУ для большинства моих процессов, но все еще были некоторые проблемы. Мой обычный МО должен был использовать очень маленький минимальный размер кучи 16m, даже с максимальной кучей в несколько гигабайт, а затем включить инкрементный GC. Это сводило паузы к минимуму. Теперь это не работает, и мне пришлось увеличить минимальный размер примерно до того, что я ожидал использовать в среднем в куче, и это сработало очень хорошо. У меня все еще включен инкрементный GC, но я буду пробовать его без. Никаких пауз и тому кажется, бежит очень быстро. Итак, я думаю, мораль истории заключается в том, что не ожидайте, что ваши настройки памяти отлично переведут с 1.6 на 1.7.


G1 делает приложение намного более гибким: латентность приложения повысится - приложение можно назвать "soft-real-time". Это делается путем замены двух видов пробегов GC (небольших второстепенных и одного большого на Tenured Gen) на равные по размеру маленькие.

для более подробной информации смотрите на это: http://geekroom.de/java/java-expertise-g1-fur-java-7/


Я работаю с Java, для малой и большой кучи, и вопрос о GC и полном GC появляется каждый день, так как ограничения могут быть более строгими, чем другие : в определенной среде 0,1 секунды scavenger GC или полного GC, убивают просто fonctionnalité, и имеют мелкозернистую конфигурацию и возможность важна (CMS, iCMS, другие ... цель здесь иметь самое лучшее возможное время на ответ с почти обработкой в реальном времени (здесь обработка в реальном времени часто госпожа 25), поэтому, в принципе, любые улучшения в GC ergonomy ans heuristique приветствуются !


Я использую G1GC на Java 8, а также с Groovy (также Java 8), и я делаю различные виды рабочих нагрузок, и overally g1gc работает следующим образом:

  • использование памяти очень низкое, например, 100 МБ вместо 500 МБ по сравнению с настройками Java по умолчанию

  • время отклика является последовательным и очень низким

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

  • при работе с Tomcat, который многопоточен, общая производительность на 30% лучше, а использование памяти намного ниже, а время отклика намного ниже.

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


Не рекомендуется использовать java8 w / G1GC для расчета плавающей точки с hotspot-like JVM. Это опасно для целостности и точности.

https://bugs.openjdk.java.net/browse/JDK-8148175

JDK-8165766

JDK-8186112