Рубрики
Без рубрики

Руководство по управлению памятью JVM и устранению неполадок – 1

Эта серия представляет собой краткое изложение курса Oracle по устранению неполадок JVM, в котором дается обзор памяти JVM… С тегами java, jvm, kotlin, программирование.

Эта серия представляет собой краткое изложение курса Oracle JVM по устранению неполадок , в котором дается обзор управления памятью JVM, опций сборки мусора Hotspot VM, различных ошибок памяти и способов их устранения.

В этом посте (часть 1) мы рассмотрим, как JVM управляет памятью и ее различными сборщиками мусора.

Вы можете найти Часть 2 здесь:

JVM Primer Часть 2 – Проблемы с отладкой памяти

Раунак Рамакришнан ・ 16 мая 18 ・ 5 минут чтения

Обзор управления памятью JVM

JVM обеспечивает автоматическое управление памятью, чтобы освободить программиста от ручного управления памятью. Новые объекты выделяются в кучной памяти. Корневой набор состоит из указателей на внешнюю память, статических переменных, потоков, ссылок JNI и внутренних структур JVM. Объекты, доступные непосредственно из корневого набора, должны храниться в куче. Объекты, доступные из любого из доступных объектов, также должны находиться в куче. Эта группа объектов – единственные, которые могут быть использованы программой. Недоступные объекты (мусор) удаляются с помощью процесса, называемого сборкой мусора (GC) . Достижимые объекты уплотняются то есть переместился в смежное пространство в куче. Это важно, так как в противном случае куча станет фрагментированной .

Поколения GC и пространства памяти в Hotspot

Когда JVM запускается, он запрашивает некоторую память у операционной системы. Эта память разделена на различные пространства.

Пространства памяти в JVM до JDK 8

  • Отдельные пулы содержат объекты разных возрастных диапазонов
  • GC JVM является |/поколенческим и основан на гипотезе о том, что: Большинство объектов умирают молодыми

    • Несколько ссылок от более старых объектов к более молодым
    • Существует 2 поколения объектов:
  • молодые: маленькие и часто собираемые (незначительная коллекция). Объекты, пережившие пороговое количество GCS, переходят в старое поколение.
    • старый: большой, собирается нечасто (крупный GC)
    • До JDK 8 также существовала
  • постоянная генерация , которая предназначалась для хранения представлений классов и метаданных, интернированных строк и статики классов. Это было заменено metaspace в JDK 8 и более поздних версиях. Метапространство
  • выделяется в собственной памяти. Он управляется с помощью параметров JVM MetaspaceSize для начального размера и MaxMetaspaceSize для максимального. Если включен параметр

    • UseCompressedClassPointers , для хранения классов и их метаданных используются 2 области памяти – метапространство и сжатое пространство классов . 64-разрядные указатели классов представлены с 32-разрядными смещениями для экономии места. На метаданные класса ссылаются 32-разрядные смещения, хранящиеся в сжатом пространстве классов. По умолчанию сжатое пространство класса составляет 1 ГБ. Кэш кода используется для хранения скомпилированного кода, сгенерированного JIT (Just in time optimizer), выделяемого из встроенной памяти и управляемого Code Cache Sweeper

Сборщики мусора в Hotspot JVM

JVM имеет разные методы сбора мусора для разных поколений объектов. Некоторые из них описаны ниже:

  • Коллекция молодого поколения
    • Serial – Stop-the-world (STW), копирующий коллектор, однопоточный
    • ParNew – STW, сборщик копий, несколько потоков GC
    • Параллельная очистка – STW, сборщик копий, несколько потоков GC
  • Коллекция старого поколения
    • Серийный Старый – STW, марка-развертка-компактный коллектор, однопоточный
    • CMS – В основном параллельная, низкая пауза
    • Параллельный сборщик старого уплотнения, несколько потоков GC
  • G1: предназначен для больших куч и предлагает предсказуемые короткие паузы.
    • Имеет различную компоновку памяти для нескольких поколений
    • Один и тот же коллекционер для всех поколений

Параметры GC для JDK

Это флаги опций, передаваемые JVM для указания того, какой GC использовать:

  • UseSerialGC: Серийный номер + Старый серийный номер
  • Используйте parnewgc: ParNew + SerialOld . В JDK 9 используется CMS для старого поколения
  • Useconcon marksweepgc: ParNew + CMS + Старый серийный номер
    • CMS использовала большую часть времени для сбора старого поколения. Последовательный порт используется при сбое параллельного режима.
    • CMS выполняет большую часть работы одновременно с потоками приложений.
      • Никакое уплотнение кучи не приводит к фрагментации. Имеет плавающий мусор и требует больших размеров кучи.
      • Свободное пространство поддерживается в виде связанных списков. Выделение дорого по сравнению с выделением указателя.
      • Дополнительные накладные расходы на молодые коллекции
    • Устарел в JDK 9
  • UseParallelGC: Параллельная Очистка + Параллельная Очистка.
    • Максимизирует пропускную способность.
    • GC по умолчанию до JDK 9
  • UseG1GC – G1 для обоих поколений
    • GC в серверном стиле для многоядерных машин с большим объемом памяти
    • Низкие паузы GC с высокой вероятностью при попытке добиться высокой пропускной способности
    • Уплотнительный коллектор. Низкие паузы без фрагментации
    • Улучшенная эргономика GC. Параллельные потоки и некоторые задачи выполняются одновременно с потоками приложений
    • Доступно начиная с JDK 7u4 и по умолчанию в JDK 9

Для получения более подробной информации о настройке сборщика мусора ознакомьтесь с официальным руководством по настройке GC

Незначительный GC или Как собирается молодое поколение:

  1. Когда пространство Eden в young gen заполнено полностью, доступные объекты помечаются и перемещаются в пространство ToSurvivorSpace
  2. Объекты из пространства выживших, которые доступны, перемещаются в пространство выживших
  3. Объекты из пространства Выживших, которые пересекли порог, переводятся в старое поколение
  4. Эдем становится пустым и готов к новым распределениям
  5. В Места для выживших и обратно переключаются

Примечания к сборнику Mark-Sweep-Compact (серийный номер Старый):

  • Фаза пометки: отмечает все живые объекты
  • Фаза очистки: очистка кучи, идентифицирующая мусор
  • Фаза скольжения: GC выполняет скользящее уплотнение, перемещая живые объекты в начало кучи

Оригинал: “https://dev.to/rrampage/a-primer-on-jvm-memory-management-and-troubleshooting—1-12b6”