Может ли Sun JVM справиться с гигантскими размерами кучи без проблем и как?
Я слышал, что несколько человек утверждают, что вы не можете масштабировать размер кучи JVM. Я слышал, что практический предел составляет 4 гигабайта (я слышал, как это говорит консультант IBM), 10 гигабайт, 32 гигабайта и т.д.... Я просто не могу поверить ни одному из этих номеров и задавался вопросом о проблеме сейчас какое-то время.
Итак, у меня есть три вопроса: я надеюсь, что кто-то с опытом может ответить:
- Учитывая следующий пример, как бы вы настроили настройки кучи и GC?
- Появятся ли заметные hickup (паузы JVM и т.д.), которые будут замечены конечными пользователями?
- Должно ли это действительно работать? Я думаю, что это должно быть.
Случай:
- 64-битная платформа
- 64 ядра
- 64 гигабайта памяти
- Сервер приложений обращен к клиенту (т.е. сервер веб-приложений Jboss/tomcat). Полные паузы в JVM, вероятно, будут замечены конечными пользователями.
- Sun JVM, возможно 1.5
Чтобы доказать, что я не прошу вас, ребята, выполнить мою домашнюю работу, вот что я придумал:
-
-XX:+UseConcMarkSweepGC -XX:+AggressiveOpts -XX:+UnlockDiagnosticVMOptions -XX:-EliminateZeroing -Xmn768m -Xmx55000m
- CMS должна уменьшать количество пауз, хотя это связано с накладными расходами. Другие настройки для CMS, по-видимому, автоматически устанавливаются на количество процессоров, поэтому они кажутся мне здравомыслящими. Остальное, что я добавил, - это дополнительные функции, которые могут быть хорошими или плохими в целом для производительности, и они, вероятно, должны быть протестированы.
- Определенно.
Ответы
Ответ 1
Я думаю, что кому-то будет сложно дать вам что-то большее, чем общие советы, не зная о своем заявлении.
Я бы предположил, что вы используете VisualGC (или плагин VisualGC для VisualVM) на самом деле посмотрите на то, что делает сборщик мусора, когда ваше приложение работает. Как только вы поймете, как GC работает вместе с вашим приложением, будет гораздо проще настроить его.
Ответ 2
# 1. Учитывая следующий случай, как бы вы настроили настройки кучи и GC?
Во-первых, наличие 64 гигабайт памяти не означает, что вы должны использовать их все для одной JVM. На самом деле это скорее означает, что вы можете запустить многие из них. Тогда невозможно ответить на ваш вопрос без какого-либо доступа к вашему компьютеру и приложению в measure и проанализировать вещи (зная, что делает ваше приложение, недостаточно). И нет, я не прошу получить доступ к вашей среде:)
# 2. Будут ли заметные hickup (паузы JVM и т.д.), Которые будут замечены конечными пользователями?
Цель настройки - найти хороший компромисс между частотой и продолжительностью (основных) GC. С кучей ~ 55 г, GC не будет частым, но, безусловно, займет заметное время (чем больше куча, тем больше основной GC). Использование параллельного или параллельного сборщика мусора поможет в многопроцессорных системах, но не полностью решает эту проблему. Зачем вам ~ 55г (это мега ультра огромная для webapp IMO), что мой вопрос. Я бы предпочел запустить много кластерных JVM для обработки нагрузки, если это необходимо (в какой-то момент база данных станет узким местом в любом случае с ориентированным на данные приложением).
# 3. Должно ли это действительно работать? Я думаю, что это должно быть.
Хм... не уверен, что у меня вопрос. Что такое "this"? Создание экземпляра JVM с большой кучей? Да, должно. Это эквивалентно запуску нескольких JVM? Нет, конечно нет.
PS: 4G - это максимальное теоретическое ограничение кучи для 32-разрядной JVM, работающей в 64-разрядной операционной системе (см. Почему я не могу получить большая куча с 32-разрядной JVM?)
PPS: на 64-битных виртуальных машинах у вас есть 64 бита адресности для работы, в результате чего максимальный размер кучи Java ограничен только количеством физической памяти и пространства подкачки, которое предоставляет ваша система. (см. Какую большую кучу можно создать с помощью 64-разрядной виртуальной машины?)
Ответ 3
Очевидно, размер кучи не является неограниченным, и чем больше размер кучи, тем больше ваш JVM в конечном итоге будет тратить на GC. Хотя я думаю, что можно установить размер кучи достаточно высоко на 64-битной JVM, я все еще думаю, что это не очень практично. Совет здесь лучше иметь несколько JVM, работающих с теми же параметрами, то есть кластер узлов JBoss/Tomcat, работающих на одной физической машине, и вы получите лучшую пропускную способность.
EDIT. Также ваше поведение в GC зависит от таксономии вашей кучи. Если у вас много короткоживущих объектов, и каждый запрос на сервер создает их много, тогда ваш GC будет собирать много мусора очень часто и, следовательно, при большом размере кучи, это приведет к более длительным паузам. Если у вас очень много долгоживущих объектов (например, кеширование большинства ваших данных в памяти), а количество короткоживущих объектов не так уж и велико, то с большим размером кучи в порядке.
Ответ 4
Как уже писал Крис Райс, я бы не ожидал каких-либо очевидных проблем с GC для размеров кучи до 32-64 ГБ, хотя, конечно, может быть какая-то точка вашей логики приложения, которая может вызвать проблемы.
Не имеет прямого отношения к GC, но я бы порекомендовал вам выполнить реалистичный тест нагрузки на вашей производственной системе. Раньше я работал над проектом, где у нас была аналогичная настройка (относительно большая, сгруппированная настройка JBoss/Tomcat для обслуживания общедоступного веб-приложения), и без преувеличения JBoss не очень хорошо себя ведет при высокой нагрузке или с большим количеством одновременных если вы используете EJB. JBoss проводит много времени в синхронизированных блоках при доступе к пулам экземпляров EJB и управлении ими, и если вы выберете кластер, он даже дожидается внутрикластерной сетевой связи в этих синхронизированных блоках. Будьте особенно осведомлены о плохо выполняемой репликации состояний, если вы используете SFSB.
Ответ 5
Только для добавления некоторых дополнительных переключателей я бы использовал по умолчанию: -Xms55g может помочь уменьшить время разгона, поскольку он освобождает Java от необходимости проверять, может ли он вернуться к исходному размеру и позволяет также улучшить внутреннюю начальную калибровку области памяти.
Кроме того, мы сделали хороший опыт работы с NewSize, чтобы дать вам большой молодой размер, чтобы избавиться от кратковременного мусора: -XX: NewSize = 1g. Кроме того, большинство webapps создают много мусора, который никогда не передержит обработку запроса. Вы даже можете сделать это больше. С Xms55g VM резервирует большой кусок уже. Возможно, сокращение может помочь.
-Xincgc помогает постепенно очищать молодое поколение и часто возвращать процессор к пользовательским потокам.
-XX: CMSInitiatingOccupancyFraction = 70 Если вы действительно заполняете всю эту память, попробуйте запустить сборку мусора CMS раньше.
-XX: + CMSIncrementalMode помещает CMS в инкрементный режим, чтобы чаще возвращать процессор в пользовательские потоки.
Присоединитесь к процессу с помощью jstat -gc -h 10 <pid> 1s
и посмотрите, как работает GC.
Будете ли вы действительно заполнять память? Я предполагаю, что 64cpus для обработки запросов может даже работать с меньшим объемом памяти. Что вы там храните?
Ответ 6
В зависимости от вашего анализа паузы GC вы можете реализовать Incremental, в результате чего длительная пауза может быть разбита за период времени.
Ответ 7
Я обнаружил, что архитектура памяти играет роль в больших объемах памяти. Приложения вообще не работают, если они используют более одного банка памяти. Вероятно, JVM также страдает, особенно GC, который должен охватить всю память.
Если у вас есть приложение, которое не вписывается в один банк памяти, ваше приложение должно извлечь память, которая не является локальной для процессора, и использовать память локально для другого процессора.
В linux вы можете запустить numactl -hardware, чтобы увидеть компоновку процессоров и банков памяти.