Поиск по сайту:

Сборка мусора в Java


Сборка мусора в java — одна из продвинутых тем. Знание Java GC помогает нам точно настроить производительность нашего приложения во время выполнения.

Сборка мусора в Java

  • В Java программистам не нужно заботиться об уничтожении неиспользуемых объектов. Об этом позаботится сборщик мусора.
  • Сборщик мусора — это куча памяти, уничтожающая недоступные объекты.
  • Недостижимые объекты – это объекты, на которые больше не ссылается ни одна часть программы.
  • Мы можем выбрать сборщик мусора для нашей Java-программы с помощью параметров JVM, мы рассмотрим их в следующем разделе этого руководства.

Как работает автоматическая сборка мусора?

Автоматическая сборка мусора — это процесс просмотра памяти кучи, выявления (также известного как «маркировка») недоступных объектов и их уничтожения с помощью уплотнения. Проблема с этим подходом заключается в том, что по мере увеличения количества объектов мусор Время сбора постоянно увеличивается, так как нужно перебрать весь список объектов в поисках недостижимого объекта.Однако эмпирический анализ приложений показывает, что большинство объектов недолговечны.Такое поведение было использовано для повышения производительности JVM, а принятая методология обычно называется сборкой мусора поколений. В этом методе пространство кучи делится на поколения, такие как молодое поколение, старое или постоянное поколение и постоянное поколение. Пространство кучи молодого поколения — это новое, в котором все новые Объекты создаются.После того, как он заполняется, происходит небольшая сборка мусора (также известная как Minor GC), что означает, что все мертвые объекты из этого поколения уничтожаются. процесс идет быстро, потому что, как видно из графика, большинство из них мертвы. Уцелевшие объекты в молодом поколении стареют и со временем переходят к старшим поколениям. Старое поколение используется для хранения долгоживущих объектов. Как правило, для объекта молодого поколения устанавливается пороговое значение, и когда этот возраст достигается, объект перемещается в старое поколение. В конце концов, нужно собрать старое поколение. Это событие называется Major GC (крупная сборка мусора). Часто это намного медленнее, потому что включает все живые объекты. Кроме того, существует Full GC, что означает очистку всей кучи — как молодых, так и старых пространств поколения. Наконец, вплоть до Java 7 существовало постоянное поколение (или Perm Gen), которое содержало метаданные, необходимые JVM для описания классов и методов, используемых в приложении. Он был удален в Java 8.

Сборщики мусора Java

Фактически JVM предоставляет четыре разных сборщика мусора, все они относятся к поколениям. Каждый из них имеет свои преимущества и недостатки. Выбор того, какой сборщик мусора использовать, лежит на нас, и могут быть существенные различия в пропускной способности и паузах приложений. Все это разделяет управляемую кучу на разные сегменты, используя давние предположения о том, что большинство объектов в куче недолговечны и должны быть быстро переработаны. Итак, четыре типа сборщиков мусора:

Серийный GC

Это простейший сборщик мусора, предназначенный для однопоточных систем и небольшого размера кучи. Зависает все приложения во время работы. Можно включить с помощью параметра JVM -XX:+UseSerialGC.

Параллельный/пропускной GC

Это коллектор JVM по умолчанию в JDK 8. Как следует из названия, он использует несколько потоков для сканирования пространства кучи и выполнения уплотнения. Недостатком этого сборщика является то, что он приостанавливает потоки приложения при выполнении вспомогательной или полной сборки мусора. Это лучше всего подходит, если приложения могут обрабатывать такие паузы и пытаться оптимизировать нагрузку ЦП, вызванную сборщиком.

Сборщик CMS

Алгоритм сборщика CMS (\concurrent-mark-sweep) использует несколько потоков (\concurrent) для сканирования кучи (\mark) в поисках неиспользуемых объектов, которые можно переработать (sweep). Этот сборщик переходит в режим Stop-The-World(STW) в двух случаях: - При инициализации начальной разметки корней, т.е. объекты в старом поколении, которые доступны из точек входа потока или статических переменных — когда приложение изменило состояние кучи во время одновременного выполнения алгоритма и вынудило его вернуться и сделать некоторые последние штрихи, чтобы убедиться, что оно имеет право отмеченные объекты. Этот коллекционер может столкнуться с неудачами в продвижении. Если некоторые объекты из молодого поколения должны быть перемещены в старое поколение, а сборщик не успел освободить место в пространстве старого поколения, произойдет сбой продвижения. Чтобы предотвратить это, мы можем предоставить больше размера кучи старому поколению или предоставить сборщику больше фоновых потоков.

коллектор G1

  1. Фаза только для молодых: эта фаза включает только объекты молодого поколения и продвигает их к старому поколению. Переход между фазой только молодых и фазой освоения пространства начинается, когда старое поколение занято до определенного порога, т.е. пороговое значение начальной занятости кучи. В настоящее время G1 планирует выпуск коллекции Initial Mark только для молодых людей вместо обычной коллекции только для молодых людей.
  2. Начальная маркировка: этот тип коллекции начинает процесс маркировки в дополнение к обычной коллекции только для молодых. Параллельная маркировка определяет, что все действующие в настоящее время объекты в регионах старого поколения должны быть сохранены для следующей фазы освоения пространства. Пока маркировка еще не завершена, могут происходить регулярные сборы только для молодых особей. Маркировка заканчивается двумя специальными паузами «останови мир»: «Замечание» и «Очистка».
  3. Примечание: эта пауза завершает саму маркировку и выполняет глобальную обработку ссылок и выгрузку классов. Между Remark и Cleanup G1 одновременно вычисляет сводку информации о живучести, которая будет завершена и использована в паузе Cleanup для обновления внутренних структур данных.
  4. Очистка: эта пауза также захватывает полностью пустые регионы и определяет, последует ли на самом деле фаза освобождения пространства. Если следует этап освоения пространства, этап только для молодых завершается одной коллекцией только для молодых.
  5. Этап освоения пространства: этот этап состоит из нескольких смешанных коллекций — помимо регионов молодого поколения, также эвакуируются живые объекты регионов старого поколения. Фаза освоения пространства заканчивается, когда G1 определяет, что эвакуация большего количества регионов старого поколения не даст достаточно свободного места, которое стоит затраченных усилий.

G1 можно включить с помощью флага –XX:+UseG1GC. Эта стратегия уменьшила вероятность того, что куча будет исчерпана до того, как фоновые потоки закончат поиск недоступных объектов. Кроме того, он уплотняет кучу на ходу, что сборщик CMS может делать только в режиме STW. В Java 8 реализована красивая оптимизация с помощью сборщика G1, которая называется дедупликацией строк. Как мы знаем, массивы символов, представляющие наши строки, занимают большую часть пространства кучи. Была сделана новая оптимизация, которая позволяет сборщику G1 идентифицировать строки, которые дублируются более одного раза в нашей куче, и модифицировать их, чтобы они указывали на один и тот же внутренний массив char[], чтобы избежать ненужного размещения нескольких копий одной и той же строки в куче. . Мы можем использовать аргумент JVM -XX:+UseStringDeduplication, чтобы включить эту оптимизацию. G1 — сборщик мусора по умолчанию в JDK 9.

Java 8 PermGen и метапространство

Как упоминалось ранее, пространство постоянного поколения было удалено, начиная с Java 8. Итак, теперь JVM JDK 8 HotSpot использует собственную память для представления метаданных класса, которая называется метапространством. Большая часть выделений для метаданных класса производится из собственной памяти. Кроме того, есть новый флаг MaxMetaspaceSize, чтобы ограничить объем памяти, используемый для метаданных класса. Если мы не укажем значение для этого, метапространство изменяет размер во время выполнения в соответствии с требованиями работающего приложения. Сборка мусора метапространства запускается, когда использование метаданных класса достигает предела MaxMetaspaceSize. Чрезмерная сборка мусора Metaspace может быть признаком классов, утечки памяти загрузчиков классов или неадекватного размера для нашего приложения. Вот и все для сборки мусора в java. Надеюсь, вы поняли, какие сборщики мусора есть в java. Ссылки: G1 ГК.