Разница между MetaspaceSize и MaxMetaspaceSize анализа исходного кода JVM

JVM

Когда JVM загружает класс, ей необходимо записать метаданные класса, которые будут храниться в отдельной области памяти, в Java 7 это пространство называетсяПостоянное поколение (Permgen), в Java 8 используйтеМетапространствозаменяет постоянное поколение. Данные, хранящиеся в постоянном поколении и метапространстве, не совсем совпадают, и другие элементы, не связанные с метаданными класса, также хранятся в постоянном поколении.

Как и в нашей предыдущей статье016: Как строковые объекты хранятся в JVMКак упоминалось в Java 7, строковые константы были перенесены из постоянной генерации в область кучи, но постоянная генерация не была полностью преобразована. До Java 8 преобразование постоянного поколения не завершено полностью.Данные, сохраняемые в метапространстве, намного чище, чем в постоянном поколении, то есть метаданные класса.Эта информация полезна только во время компиляции или JVM время выполнения.

теоретическое исследование

После использования Java 8 есть два параметра JVM о метапространстве:-XX:MetaspaceSize=Nа также-XX:MaxMetaspaceSize=N, для 64-разрядной JVM начальный размер метапространства по умолчанию составляет 20,75 МБ, а максимальное значение метапространства по умолчанию не ограничено. MaxMetaspaceSize используется для установки максимального значения области метапространства.Это значение можно получить через MemoryPoolBean в mxbean.Если этот параметр не задан, то максимальное значение, полученное через mxbean, равно -1, что означает бесконечность.

Поскольку для настройки размера метапространства требуется полная сборка мусора, это очень дорогостоящая операция.Если при запуске приложения происходит большое количество полных сборок мусора, это обычно связано с изменением размера постоянной генерации или метапространства. в этой ситуации обычно рекомендуется использовать В параметрах JVM установите для MetaspaceSize и MaxMetaspaceSize одно и то же значение и установите для него большее значение, чем начальное значение.Для машины с физической памятью 8G обычно я устанавливаю оба значения до 256M (PS: читатели могут настроить в соответствии с реальной ситуацией).

Анализ исходного кода

MetaspaceSize указывает порог для срабатывания FGC из-за недостаточного использования метапространства в первый раз.Он работает только для срабатывания.Причина: сборщик мусора внутренне использует переменные_capacity_until_GCЧтобы определить, достигла ли область метапространства порогового значения, код инициализации выглядит следующим образом:

void MetaspaceGC::initialize() {
  // Set the high-water mark to MaxMetapaceSize during VM initializaton since
  // we can't do a GC during initialization.
  _capacity_until_GC = MaxMetaspaceSize;
}

Сборщик GC переработает метапространство и вычислит новыйcapacityuntil_GC, будущий FGC не имеет ничего общего с MetaspaceSize.屏幕快照 2018-10-16 下午6.39.08.png

Если MetaspaceSize не задан, по умолчаниюcapacityuntil_GC составляет около 20M, конкретный код выглядит следующим образом: - assets/2019/10/4/16d97024b10550ee~tplv-t2oaga2asx-image.image)*** Этот выпуск посвящен таким темам, как серверные технологии, устранение неполадок и оптимизация JVM, вопросы собеседования по Java, личностный рост и самоуправление, и предоставляет читателям опыт работы и роста разработчиков первой линии, я надеюсь, что вы сможете что-то здесь извлечь.javaadu