Должен ли я установить MaxMetaspaceSize?

Итак, после вопроса this, быстро стало ясно, что важным вопросом является не "как я могу", а "должен ли я"?

У нас есть клиенты, с которых мы переходим с Java7 на Java8 (используя Tomcat7). Java7 потребовал установки MaxPermSize, , а некоторые клиенты увеличили свой максимальный размер по умолчанию, установленный установщиком из-за индивидуальных потребностей и использования.

Должен ли я установить --XX:MaxMetaspaceSize (в предыдущий параметр -XX:MaxPermSize) для клиентов, которые определили пользовательский макс? Как насчет новых установок? Должен ли мы установить --XX:MaxMetaspaceSize вообще?

Каковы плюсы и минусы такого решения?

Ответ 1

Как я прокомментировал предыдущий ответ, причины для установки ограничения на эти пулы памяти различны.

Если ваши пользователи ранее увеличили MaxPermSize выше значения по умолчанию, вероятно, было либо избежать ошибок полного GC/параллельного режима с CMS, либо потому, что их приложения действительно нуждались в большом пространстве perm gen.

Уменьшение предела метапасности от его эффективного бесконечного дефолта будет иметь совершенно другую цель: избегать неограниченного роста метастази.

Дело в том, что это только верхний предел. Фактически зафиксированный, то есть текущий размер метапоса будет меньше. Фактически, существует параметр под названием MaxMetaspaceFreeRatio (по умолчанию 70%), что означает, что фактический размер метапроцессора никогда не превысит 230% от его занятости.

И для того, чтобы он расти, сначала нужно было бы заполнить, заставив сборку мусора (metaspace full) в попытке освободить объекты и только тогда, когда она не сможет выполнить свою цель MinMetaspaceFreeRatio (по умолчанию 40%), она расширит текущая метапасность не должна превышать 230% от занятости после цикла GC.

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

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

Ответ 2

Ответ от комментариев @eckes:

i установил бы максимум, который достаточно велик, чтобы не запускать в нормальном режиме ситуации. Причина, по которой я говорю, заключается в том, что система может действовать очень беспорядочно и трудно контролировать, если родная память истощается или дикая происходит обмен. Mich хуже, чем OOM или Java замораживание. Например используя 2 ГБ (чтобы система могла иметь 2 гб буферов бесплатно как минимум)

Ответ 3

Просто чтобы выразить противоположное мнение, можно сделать так, чтобы ВСЕГДА устанавливали MaxMetaspaceSize. Группировка всего набора приложений в мире в 10 (бинарные - подумайте об этом) группы позволяет обсуждать, почему. Помните, что установка ограничения ограничивает контроль, только когда будет собрана сборка мусора (GC) этого пространства.

Группа 01: Приложения со всеми нединамическими классами

Эта группа помещает вас в стабилизированную полосу, о которой говорилось выше. В этом случае размер, который нужно установить, довольно легко определить (точно так же, как MaxPermSize был), и в любом случае GC не будет, если таковой вообще существует.

Группа 10: Приложения с динамическими классами

Учитывая распространение мощных сторонних библиотек, это не почти все приложения в этой группе? Часто вам все равно, есть ли библиотека Scala/Groovy/etc, она просто делает именно то, что вы хотите, чтобы она использовалась. Какова ценность заполнения Metaspace мусором мертвых (динамических) классов? Когда GC действительно придет, это будет дорого. Я бы предпочел ограничить размер, сделать GC более частым (но меньше времени паузы для каждого) и более легко запустить несколько приложений на одном и том же аппаратном обеспечении, не беспокоясь о том, что их отдельные метапространства работают друг с другом.