Java очень большие размеры кучи

Есть ли у кого-нибудь опыт использования очень больших кучей, 12 ГБ или выше в Java?

  • Предоставляет ли программа GC непригодность для использования?
  • Какие параметры GC вы используете?
  • Какой JVM, Sun или BEA лучше подходят для этого?
  • Какая платформа, Linux или Windows, работает лучше в таких условиях?
  • В случае Windows есть ли разница в производительности между 64-битной Vista и XP при таких высоких нагрузках на память?

Ответ 1

Если ваше приложение не является интерактивным, а GC-паузы не являются проблемой для вас, не должно быть никаких проблем для 64-разрядной Java для обработки очень больших кучей, даже в сотнях GB. Мы также не заметили никаких проблем с стабильностью ни в Windows, ни в Linux.

Однако, когда вам нужно поддерживать низкие паузы в GC, все становится очень неприятным:

  • Забудьте о пропускной способности по умолчанию, stop-the-world GC. Это приостановит ваше приложение на несколько десятков секунд для умеренных кучей (< ~ 30 ГБ) и несколько минут для больших ( > ~ 30 ГБ). И покупка более быстрых модулей DIMM не поможет.

  • Лучшим вариантом, вероятно, является сборщик CMS, включенный -XX: + UseConcMarkSweepGC. Сборщик мусора CMS останавливает приложение только для начальной фазы маркировки и фаз замещения. Для очень маленьких куч, таких как < 4 ГБ это обычно не проблема, но для приложения, которое создает много мусора и большой кучи, этап замещения может занять довольно много времени - обычно гораздо меньше, чем полная остановка в мире, но все же может быть проблема для очень больших куч.

  • Когда сборщик мусора CMS работает недостаточно быстро, чтобы закончить работу до того, как заполненное поколение заполнится, оно возвращается к стандартному GC GC. Ожидайте ~ 30 или более секундных пауз для кучи размером 16 ГБ. Вы можете попытаться избегать этого, чтобы поддерживать долговременную скорость производства мусора для вашего приложения как можно ниже. Обратите внимание, что чем больше число ядер, запускающих ваше приложение, тем больше становится эта проблема, потому что CMS использует только одно ядро. Очевидно, будьте осторожны, нет гарантии, что CMS не вернется к коллектору STW. И когда это происходит, это обычно происходит при пиковых нагрузках, и ваше приложение мертво в течение нескольких секунд. Возможно, вы не захотите подписать SLA для такой конфигурации.

  • Ну, есть новая вещь G1. Теоретически он разработан, чтобы избежать проблем с CMS, но мы попробовали это и заметили, что:

    • Его пропускная способность хуже, чем у CMS.
    • Теоретически следует избегать сбора популярных блоков памяти в первую очередь, однако вскоре он достигает состояния, когда почти все блоки являются "популярными", а предположения основаны на просто прекращении работы.
    • Наконец, остаточный резерв по-прежнему существует для G1; спросите Oracle, когда этот код должен быть запущен. Если они говорят "никогда", спросите их, почему код есть. Таким образом, IMHO G1 действительно не делает огромную проблему кучи Java уходящей, она лишь делает ее (возможно) немного меньше.
  • Если у вас есть доллары для большого сервера с большой памятью, у вас, вероятно, также есть баксы для хорошей, аппаратной ускоренной, беспроблемной технологии GC, такой как предлагаемая Azul. У нас есть один из их серверов с оперативной памятью 384 ГБ, и он действительно работает нормально - нет пауз, 0-строк кода stop-the-world в GC.

  • Напишите проклятую часть вашего приложения, которая требует большого количества памяти на С++, например LinkedIn, с обработкой социальных графов. Вы все равно не будете избегать всех проблем, выполнив это (например, фрагментацию кучи), но было бы намного проще сохранить паузы.

Ответ 2

Я генеральный директор Azul Systems, поэтому я, очевидно, склонен к моему мнению на эту тему!:) Это сказано...

Azul CTO, Gil Tene, имеет хороший обзор проблем, связанных с Garbage Collection, и обзор различных решений в его Понимание коллекции мусора Java и What You Can Do It About, а также дополнительные подробности в этой статье: http://www.infoq.com/articles/azul_gc_in_detail.

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

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

Ответ 3

У нас есть приложение, которое мы выделяем 12-16 Гб, но оно действительно достигает 8-10 при нормальной работе. Мы используем Sun JVM (попробовали IBM, и это было немного катастрофой, но, возможно, это было невежество с нашей стороны... У меня есть друзья, которые клянутся им - это работает в IBM). До тех пор, пока вы предоставляете свою комнату для дыхания в приложении, JVM может обрабатывать большие размеры кучи с не слишком большим количеством GC. Большое количество "лишней" памяти - ключ.
Linux почти всегда более стабильна, чем Windows, и когда она нестабильна, намного проще понять, почему. Solaris тоже солидная, и вы тоже получаете DTrace:) С такими нагрузками, почему бы вам не использовать Vista или XP? Вы просто просите о неприятностях. Мы ничего не делаем с параметрами GC. Мы устанавливаем минимальное распределение равным максимуму, поэтому оно не постоянно пытается изменить размер, но это все.

Ответ 4

Я использовал размеры кучи более 60 Гбайт в двух разных приложениях под Linux и Solaris, соответственно, используя 64-битные версии (очевидно) JVM Sun 1.6.

Я никогда не сталкивался с проблемами сбора мусора с Linux-приложением, за исключением случаев, когда он приближался к пределу размера кучи. Чтобы избежать проблем с прерыванием, присущих этому сценарию (слишком много времени, затраченного на сборку мусора), я просто оптимизировал использование памяти во всей программе, так что пиковое использование было примерно на 5-10% ниже предела размера кучи 64 ГБ.

Вместе с другим приложением, работающим под Solaris, я столкнулся с серьезными проблемами сбора мусора, из-за чего вам пришлось много настраивать. Это состояло в основном из трех шагов:

  • Включение/выключение использования параллельного сборщика мусора с помощью опций -XX: + UseParallelGC -XX: + UseParallelOldGC JVM, а также управление количеством потоков GC, используемым в опции -XX: ParallelGCThreads. См. " Java SE 6 HotSpot Virtual Machine Tuning Tuning Tuning" для более подробной информации.

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

  • Выборочное использование вызова метода System.gc() в разделах key code после длительных периодов временного распределения объектов. Я знаю стандартные оговорки против использования этих вызовов и аргумент, что они обычно не нужны, но я обнаружил, что они имеют решающее значение для приручения коллекции мусора при запуске этого приложения, интенсивно использующего память.

Три вышеуказанных шага позволили сохранить это приложение в рабочем состоянии и эффективно работать при использовании кучи размером около 60 ГБ вместо того, чтобы выходить из-под контроля в ограничение размера кучи 128 ГБ, которое было на месте. Параллельный сборщик мусора, в частности, очень полезен, поскольку большие циклы сбора мусора являются дорогостоящими, когда существует много объектов, т.е. Время, необходимое для сбора основных мусора, зависит от количества объектов в куче.

Я не могу комментировать другие проблемы, связанные с платформой, в этом масштабе, и я не использовал JVM с не-Sun (Oracle).

Ответ 5

12Gb не должно быть проблемой с достойной реализацией JVM, такой как Sun Hotspot. Я бы посоветовал вам использовать Concurrent Mark и Sweep colllector (-XX: + UseConcMarkSweepGC) при использовании SUN VM.Другие вы можете столкнуться с фазами "остановить мир", все потоки были остановлены во время GC.

ОС не должна иметь большого значения для производительности GC.

Вам понадобится, конечно, 64-битная ОС и машина с достаточной физической памятью.

Ответ 6

Я рекомендую также рассмотреть вопрос о том, как взять кучу кучи и посмотреть, как использование памяти можно улучшить в вашем приложении и проанализировать дамп в чем-то вроде Eclipse MAT. На странице MAT есть несколько статей, посвященных поиску утечек памяти. Вы можете использовать jmap для получения дампа с чем-то вроде...

jmap -heap:format=b pid

Ответ 7

Если вы переключитесь на 64-битный, вы будете использовать больше памяти. Указатели становятся 8 байтами вместо 4. Если вы создаете много объектов, это может быть заметно, поскольку каждый объект является ссылкой (указателем).

Я недавно выделил 15 ГБ памяти на Java с использованием JVM Sun 1.6 без проблем. Хотя это все выделено только один раз. После начальной суммы выделяется или освобождается не так много памяти. Это было на Linux, но я думаю, что Sun JVM будет работать также и на 64-битной Windows.

Ответ 9

здесь статья о gc FROM из одного из Java Champions - http://kirk.blog-city.com/is_your_concurrent_collector_failing_you.htm

Кирк, автор пишет "Отправьте мне свои журналы GC

В настоящее время я заинтересован в изучении Sun JVM, созданных журналами GC. Поскольку эти журналы не содержат информации, относящейся к бизнесу, это должно быть легкомысленно относиться к защите информации о прориации. Все, что я прошу, чтобы в журнале вы упоминали ОС, полную информацию о версии для JRE и любые связанные с ней параметры командной строки, связанные с кучей /gc, которые вы установили. Я также хотел бы узнать, используете ли вы Grails/Groovey, JRuby, Scala или что-то другое, кроме или рядом со стороной Java. Лучшей настройкой является -Xloggc:. Имейте в виду, что этот журнал не переливается, когда он достигает предела размера вашей ОС. Если я найду что-нибудь интересное, я с удовольствием дам вам краткий обзор. "

Ответ 10

Вам следует попробовать запустить visualgc против вашего приложения. Это инструмент визуализации кучи, который является частью загрузки jvmstat на http://java.sun.com/performance/jvmstat/

Это намного проще, чем чтение журналов GC.

Он быстро помогает понять, как работают части (поколения) кучи. Хотя ваша общая куча может составлять 10 ГБ, различные части кучи будут намного меньше. GC в Eden часть кучи относительно дешевы, а полные GC в старом поколении дороги. Размещая свою кучу так, чтобы Иден был большим, а старое поколение едва ли тронуло, это хорошая стратегия. Это может привести к очень большой общей куче, но, черт возьми, если JVM никогда не касается страницы, это просто виртуальная страница, и она не должна занимать RAM.

Ответ 11

Пару лет назад я сравнивал JRockit и Sun JVM для кучи 12G. JRockit выиграл, а поддержка огромных ресурсов Linux сделала наш тестовый прогон на 20% быстрее. YMMV, поскольку наш тест был очень насыщенным процессором/памятью и был в основном однопоточным.

Ответ 12

Как упоминалось выше, если у вас есть неинтерактивная программа, сборщик мусора по умолчанию (уплотнение) должен работать хорошо. Если у вас есть интерактивная программа, и вы (1) не выделяете память быстрее, чем GC может поддерживать вверх, и (2) не создавать слишком большие временные объекты (или коллекции объектов) (относительно максимальная память JVM) для работы GC, тогда CMS для вас.

У вас возникают проблемы, если у вас есть интерактивная программа, в которой GC не хватает передышки. Это правда, независимо от того, сколько у вас памяти, но чем больше у вас памяти, тем хуже она становится. Это связано с тем, что при слишком низком объеме памяти в CMS закончится нехватка памяти, тогда как уплотняющие GC (включая G1) остановят все, пока вся память не будет проверена на мусор. Эта пауза паузы становится больше, чем больше у вас. Поверьте мне, вы не хотите, чтобы ваши сервлеты задерживались на минуту. Я написал fooobar.com/questions/14654/...

С тех пор моя компания переключилась на Azul Zing. Он по-прежнему не может справиться с тем случаем, когда вашему приложению действительно требуется больше памяти, чем у вас, но до тех пор, пока этот момент не работает, как сон.

Но, конечно, Зинг не свободен, а его специальный соус запатентован. Если у вас гораздо больше времени, чем денег, попробуйте переписать приложение, чтобы использовать кластер JVM.

На горизонте Oracle работает над высокопроизводительным GC для многогабаритных куч. Однако на сегодняшний день это не вариант.

Ответ 13

Максимальная память, на которую может обращаться XP, - 4 гигабайта (здесь). Таким образом, вы можете не использовать XP для этого (используйте 64-битные ОС).

Ответ 14

у солнца был 64-битный jvm itanium на некоторое время, хотя itanium не является популярным местом назначения. Solaris и Linux 64-битные JVM должны быть тем, чем вы должны следовать.
Некоторые вопросы

1) Ваше приложение стабильно? 2) Вы уже протестировали приложение в 32-битной JVM?
3) нормально ли запускать несколько JVM в одном окне?

Я ожидал бы, что 64-битная ОС из окон стабилизируется примерно через год или около того, но до тех пор, Solaris/linux может быть лучше.