Поскольку Java 7 по умолчанию будет использовать новую сборку мусора G1, сможет ли Java обрабатывать на порядок большую кучу без предполагаемого «разрушительного» времени паузы сборщика мусора? Кто-нибудь действительно внедрил G1 в производство, каков был ваш опыт?
Честно говоря, я видел действительно длинные паузы сборщика мусора только в очень больших кучах, намного больше, чем на рабочей станции. Чтобы прояснить мой вопрос; откроет ли G1 шлюз до кучи в сотни гб? Туберкулез?
java
garbage-collection
java-7
g1gc
Benstpierre
источник
источник
Ответы:
Похоже, цель G1 состоит в том, чтобы иметь меньшее время паузы, даже до такой степени, что у него есть возможность указать максимальное целевое время паузы.
Сборка мусора - это уже не простая сделка типа «Эй, он полный, давайте переместим все сразу и начнем заново» - это фантастически сложная многоуровневая фоновая многопоточная система. Он может выполнять большую часть своего обслуживания в фоновом режиме без каких-либо пауз, а также использует знания об ожидаемых шаблонах системы во время выполнения, чтобы помочь - например, если предположить, что большинство объектов умирает сразу после создания и т. Д.
Я бы сказал, что время паузы GC будет улучшаться, а не ухудшаться в будущих выпусках.
РЕДАКТИРОВАТЬ:
при перечитывании мне пришло в голову, что я использую Java ежедневно - Eclipse, Azureus и разрабатываемые мной приложения, и прошло ДЛИННОЕ ВРЕМЯ с тех пор, как я увидел паузу. Небольшая пауза, но вообще любая пауза.
Я видел паузы, когда я щелкаю правой кнопкой мыши по проводнику Windows или (иногда) когда подключаю определенное USB-оборудование, но с Java - вообще нет.
GC все еще проблема для кого-то?
источник
Я тестировал это с тяжелым приложением: 60-70 ГБ выделено в куче, а 20-50 ГБ используются в любое время. С такими приложениями будет преуменьшением сказать, что ваш опыт может отличаться. Я использую JDK 1.6_22 в Linux. Важны второстепенные версии - примерно до 1.6_20 в G1 были ошибки, которые вызывали случайные исключения NullPointerExceptions.
Я обнаружил, что он очень хорошо удерживает цель паузы, которую вы ему задаете большую часть времени. По умолчанию, пауза составляет 100 мс (0,1 секунды), и я сказал ему сделать половину этого (-XX: MaxGCPauseMillis = 50). Однако, как только память становится действительно нехваткой, она паникует и выполняет полную сборку мусора. С 65 ГБ это занимает от 30 секунд до 2 минут. (Количество процессоров, вероятно, не имеет значения; оно, вероятно, ограничено скоростью шины.)
По сравнению с CMS (которая не является сервером GC по умолчанию, но должна быть для веб-серверов и других приложений реального времени), типичные паузы намного более предсказуемы и могут быть намного короче. Пока мне больше везет с CMS из-за огромных пауз, но это может быть случайным; Я вижу их всего несколько раз каждые 24 часа. Я не уверен, какой из них будет более подходящим для моей производственной среды на данный момент, но, вероятно, G1. Если Oracle продолжит настройку, я подозреваю, что G1 в конечном итоге станет явным победителем.
Если у вас нет проблем с существующими сборщиками мусора, нет причин рассматривать G1 прямо сейчас. Если вы запускаете приложение с низкой задержкой, такое как приложение с графическим интерфейсом, G1, вероятно, будет правильным выбором, так как MaxGCPauseMillis установлен на очень низком уровне. Если вы запускаете приложение в пакетном режиме, G1 вам ничего не покупает.
источник
Хотя я не тестировал G1 в производственной среде, я подумал, что прокомментирую, что сборщики мусора уже проблематичны для случаев без «огромных» куч. В частности, GC может серьезно повлиять на сервисы с, скажем, 2 или 4 гигабайтами. Сборщики мусора молодого поколения обычно не вызывают проблем, поскольку они заканчиваются за однозначные миллисекунды (или, самое большее, двузначные). Но коллекции старого поколения гораздо более проблематичны, так как они занимают несколько секунд при размерах старого поколения 1 гигабайт или выше.
Теперь: теоретически CMS может здесь очень помочь, так как она может выполнять большую часть своей работы одновременно. Однако со временем будут случаи, когда он не сможет этого сделать и будет вынужден вернуться к сбору «остановить мир». И когда это произойдет (скажем, через час - не часто, но все же слишком часто), ну, держитесь за свои гребаные шляпы. Это может занять минуту или больше. Это особенно проблематично для служб, которые пытаются ограничить максимальную задержку; вместо того, чтобы обрабатывать запрос, скажем, 25 миллисекунд, теперь он занимает десять секунд или больше. Чтобы добавить вреда к оскорблению, клиенты затем часто отключают запрос и повторяют попытку, что приводит к дальнейшим проблемам (так называемый «дерьмовый шторм»).
Это одна из областей, где G1 очень надеялся помочь. Я работал в большой компании, которая предлагает облачные сервисы для хранения и отправки сообщений; и мы не могли использовать CMS, поскольку, хотя большую часть времени она работала лучше, чем параллельные разновидности, у нее случались сбои. Так что около часа все было хорошо; а затем все поразило ... и поскольку обслуживание было основано на кластерах, когда один узел попадал в проблему, другие обычно следовали (поскольку таймауты, вызванные сборщиком мусора, приводят к тому, что другие узлы считают, что узел разбился, что привело к перенаправлению).
Я не думаю, что сборщик мусора представляет собой большую проблему для приложений, и, возможно, даже некластеризованные службы страдают реже. Но все больше и больше систем объединяются в кластеры (особенно благодаря хранилищам данных NoSQL), и размеры кучи растут. Сборщики мусора OldGen суперлинейно связаны с размером кучи (это означает, что удвоение размера кучи более чем удваивает время сборки мусора, при условии, что размер набора динамических данных также удваивается).
источник
Технический директор Azul, Гил Тене, дает хороший обзор проблем, связанных со сборкой мусора, и обзор различных решений в своей презентации « Общие сведения о сборке мусора Java и что вы можете с этим сделать» , а также дополнительные подробности в этой статье: http: // www.infoq.com/articles/azul_gc_in_detail .
Сборщик мусора C4 от Azul в нашей JVM Zing работает одновременно и параллельно, и использует один и тот же механизм сборки мусора как для нового, так и для старого поколения, работая одновременно и уплотняясь в обоих случаях. Самое главное, что у C4 нет возможности остановить мир. Все уплотнения выполняются одновременно с работающим приложением. У нас есть клиенты, использующие очень большие (сотни гигабайт) с временем паузы GC в худшем случае <10 мс, а в зависимости от приложения часто меньше 1-2 мсек.
Проблема с CMS и G1 заключается в том, что в какой-то момент память кучи Java должна быть уплотнена, и оба этих сборщика мусора останавливают мир / STW (то есть приостанавливают приложение) для выполнения сжатия. Таким образом, хотя CMS и G1 могут выдвигать паузы STW, они не устраняют их. Однако Azul C4 полностью исключает паузы STW, и поэтому Zing имеет такие низкие паузы GC даже для гигантских размеров кучи.
И чтобы исправить заявление, сделанное в предыдущем ответе, Zing не требует никаких изменений в операционной системе. Он работает так же, как и любая другая JVM в неизмененных дистрибутивах Linux.
источник
Мы уже используем 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
источник
Коллектор G1 снижает влияние полных коллекций. Если у вас есть приложение, в котором вы уже сократили потребность в полных коллекциях, сборщик Concurrent map Sweep так же хорош, и, по моему опыту, имеет более короткое время сбора второстепенных.
источник
Похоже, что G1, запускающий JDK7u4, наконец-то официально поддерживается, см. RN для JDK7u4 http://www.oracle.com/technetwork/java/javase/7u4-relnotes-1575007.html .
Судя по нашему тестированию для больших JVM, настроенная CMS по-прежнему работает лучше, чем G1, но я думаю, она станет лучше.
источник
Недавно меня переехали из
CMS в G1GC с кучей 4G и 8-ядерным процессором на серверах с JDK 1.7.45 .
(JDK 1.8.x G1GC предпочтительнее 1.7, но из-за некоторых ограничений я должен придерживаться версии 1.7.45)
Я настроил следующие ключевые параметры и сохранил все остальные параметры по умолчанию.
Если вы хотите точно настроить эти параметры, прочтите эту статью о Oracle .
Основные наблюдения:
Но все же я рад, что максимальное время паузы GC меньше, чем у CMS. Я установил максимальное время паузы сборщика мусора как 1,5 секунды, и это значение еще не превышено.
Связанный вопрос SE:
Сборка мусора Java 7 (JDK 7) и документация по G1
источник
CMS может привести к медленному снижению производительности, даже если вы запускаете его без накопления зарезервированных объектов. Это происходит из-за фрагментации памяти, которую G1 якобы избегает.
Миф о том, что G1 доступен только при платной поддержке, - это всего лишь миф. Sun и теперь Oracle разъяснили это на странице JDK.
источник
G1 GC должен работать лучше. Но если установить -XX: MaxGCPauseMillis слишком агрессивно, мусор будет собираться слишком медленно. Вот почему в примере Дэвида Леппика сработал полный сборщик мусора.
источник
Я только что реализовал сборщик мусора G1 в нашем проекте Terracotta Big Memory. При работе с разными типами коллекторов G1 дал нам лучшие результаты с временем отклика менее 600 мс.
Вы можете найти результаты тестов (всего 26) здесь
Надеюсь, это поможет.
источник
Недавно я перенес часть Twicsy на новый сервер с 128 ГБ ОЗУ и решил использовать версию 1.7. Я начал использовать все те же настройки памяти, что и с 1.6 (у меня есть несколько экземпляров, выполняющих разные вещи, от 500 МБ кучи до 15 ГБ, а теперь новый с 40 ГБ), и это вообще не сработало. . 1.7, похоже, использует больше кучи, чем 1.6, и в первые несколько дней у меня было много проблем. К счастью, у меня было много оперативной памяти для работы, и я увеличил объем оперативной памяти для большинства моих процессов, но все еще имел некоторые проблемы. Моим обычным MO было использовать очень маленький минимальный размер кучи 16 м, даже с максимальной кучей в несколько гигабайт, а затем включить инкрементный сборщик мусора. Это сводило паузы к минимуму. Однако сейчас это не работает, и мне пришлось увеличить минимальный размер примерно до того, что я ожидал использовать в среднем в куче, и это сработало очень хорошо. У меня все еще включен инкрементный сборщик мусора, но я попробую и без него. Теперь никаких пауз, и кажется, что все идет очень быстро. Итак, я думаю, что мораль этой истории в том, что не ожидайте, что ваши настройки памяти будут идеально переведены с 1,6 на 1,7.
источник
G1 делает приложение намного более гибким: увеличивается его латантность - приложение можно назвать «мягким в реальном времени». Это достигается заменой двух типов запусков сборщика мусора (маленьких второстепенных и одного большого на Tenured Gen) на малые равные по размеру.
Подробнее см. Здесь: http://geekroom.de/java/java-expertise-g1-fur-java-7/
источник
Я работаю с Java для маленькой и большой кучи, и вопрос о GC и Full GC появляется каждый день, так как ограничения могут быть более строгими, чем другие: в определенной среде 0,1 секунды мусорщика GC или Full GC, kill просто fonctionnalité, иметь детальную конфигурацию и возможности (CMS, iCMS, другие ... цель здесь, чтобы иметь наилучшее возможное время отклика с обработкой почти в реальном времени (здесь обработка в реальном времени часто составляет 25 мс) Итак, в принципе, любые улучшения в эргономике и эвристике ГХ приветствуются!
источник
Я использую G1GC на Java 8, а также с Groovy (также Java 8), и я выполняю различные виды рабочих нагрузок, и в целом G1GC работает следующим образом:
Использование памяти очень низкое, например, 100 МБ вместо 500 МБ по сравнению с настройками Java по умолчанию.
Время отклика стабильное и очень низкое
Производительность между настройками по умолчанию и G1GC составляет 20% замедления при использовании G1GC в худшем случае (без настройки, однопоточное приложение). Это не так много, учитывая хорошее время отклика и низкое использование памяти.
При запуске из Tomcat, который является многопоточным, общая производительность на 30% выше, а использование памяти намного ниже, а время отклика намного меньше.
Таким образом, в целом при использовании действительно различных рабочих нагрузок G1GC является очень хорошим сборщиком для Java 8 для многопоточных приложений, и даже для однопоточных есть некоторые преимущества.
источник
Не рекомендуется использовать java8 с G1GC для вычисления с плавающей точкой с JVM, подобной хот-споту. Это опасно для целостности и точности приложения.
https://bugs.openjdk.java.net/browse/JDK-8148175
JDK-8165766
JDK-8186112
источник