1. Обзор
В этом кратком руководстве мы покажем основы различных реализаций JVM Сборки мусора (GC) . Кроме того, мы узнаем, как включить определенный тип сборки мусора в наших приложениях.
2. Краткое введение в сборку мусора
Судя по названию, похоже, что Сборка мусора занимается поиском и удалением мусора из памяти. Однако на самом деле Сборка мусора отслеживает каждый объект, доступный в пространстве кучи JVM, и удаляет неиспользуемые объекты.
Проще говоря, GC работает в два простых шага, известных как Маркировка и развертка:
- Пометка – это место, где сборщик мусора определяет, какие части памяти используются, а какие нет
- Развертка – этот шаг удаляет объекты, идентифицированные на этапе “пометка” .
Преимущества:
- Нет ручной обработки выделения/освобождения памяти, поскольку неиспользуемое пространство памяти автоматически обрабатывается GC
- Никаких накладных расходов на обработку Болтающийся указатель
- Автоматическое управление утечкой памяти ( GC само по себе не может гарантировать полное решение проблемы утечки памяти, однако оно заботится о значительной ее части)
Недостатки:
- Поскольку JVM должен отслеживать создание/удаление ссылок на объекты, это действие требует большей мощности процессора, чем исходное приложение. Это может повлиять на производительность запросов, для которых требуется большая память
- Программисты не контролируют планирование процессорного времени, выделенного на освобождение объектов, которые больше не нужны
- Использование некоторых реализаций GC может привести к непредсказуемой остановке приложения
- Автоматическое управление памятью не будет таким эффективным, как правильное ручное выделение/освобождение памяти
3. Реализация GC
JVM имеет четыре типа реализаций GC :
- Последовательный Сборщик Мусора
- Параллельный Сборщик Мусора
- Сборщик мусора CMS
- Сборщик мусора G1
3.1. Последовательный Сборщик Мусора
Это самая простая реализация GC, так как она в основном работает с одним потоком. В результате эта GC реализация замораживает все потоки приложения при запуске . Следовательно, не рекомендуется использовать его в многопоточных приложениях, таких как серверные среды.
Тем не менее, был отличный разговор от Twitter инженеров на QCon 2012 о производительности Последовательного сборщика мусора – что является хорошим способом лучше понять этот сборщик.
Последовательный GC является сборщиком мусора для большинства приложений, которые не имеют небольших требований к времени паузы и работают на машинах клиентского типа. Чтобы включить Последовательный сборщик мусора , мы можем использовать следующий аргумент:
java -XX:+UseSerialGC -jar Application.java
3.2. Параллельный Сборщик Мусора
Это значение по умолчанию GC для JVM и иногда называется сборщиками пропускной способности. В отличие от Последовательного сборщика мусора , этот использует несколько потоков для управления пространством кучи . Но он также замораживает другие потоки приложений при выполнении GC .
Если мы используем этот GC , мы можем указать максимальную сборку мусора потоков и время паузы, пропускную способность и площадь |/(размер кучи).
Количество потоков сборщика мусора можно контролировать с помощью параметра командной строки -XX:ParallelGCThreads= .
Цель максимального времени паузы (промежуток [в миллисекундах] между двумя GC )задается с помощью параметра командной строки -XX:MaxGCPauseMillis= .
Максимальная целевая пропускная способность (измеряемая в отношении времени, затраченного на сборку мусора, по сравнению со временем, затраченным вне сборки мусора) задается параметром командной строки -XX:GCTimeRatio=.
Максимальный объем памяти кучи (объем памяти кучи, необходимый программе во время работы) задается с помощью параметра -Xmx.
Чтобы включить Параллельный сборщик мусора , мы можем использовать следующий аргумент:
java -XX:+UseParallelGC -jar Application.java
3.3. Сборщик мусора CMS
Реализация Concurrent Mark Sweep (CMS) использует несколько потоков сборщика мусора для сбора мусора. Он предназначен для приложений, которые предпочитают более короткие паузы в сборке мусора и могут позволить себе совместно использовать ресурсы процессора со сборщиком мусора во время работы приложения.
Проще говоря, приложения, использующие этот тип GC, в среднем реагируют медленнее, но не перестают реагировать на сборку мусора.
Здесь следует отметить, что, поскольку этот GC является параллельным, вызов явной сборки мусора, такой как использование System.gc() во время работы параллельного процесса, приведет к сбою |/параллельного режима/Прерыванию .
Если более 98% общего времени тратится на сборку мусора CMS и восстанавливается менее 2% кучи, то OutOfMemoryError выбрасывается CMS | сборщиком . При необходимости эту функцию можно отключить, добавив в командную строку параметр -XX:-UseGCOverheadLimit .
Этот коллектор также имеет режим, известный как инкрементный режим, который устарел в Java SE 8 и может быть удален в будущем крупном выпуске.
Чтобы включить сборщик мусора CMS , мы можем использовать следующий флаг:
java -XX:+UseParNewGC -jar Application.java
Начиная с Java 9 , сборщик мусора CMS устарел . Поэтому JVM печатает предупреждающее сообщение, если мы попытаемся его использовать:
>> java -XX:+UseConcMarkSweepGC --version Java HotSpot(TM) 64-Bit Server VM warning: Option UseConcMarkSweepGC was deprecated in version 9.0 and will likely be removed in a future release. java version "9.0.1"
Более того, Java 14 полностью отказался от поддержки CMS:
>> java -XX:+UseConcMarkSweepGC --version OpenJDK 64-Bit Server VM warning: Ignoring option UseConcMarkSweepGC; support was removed in 14.0 openjdk 14 2020-03-17
3.4. Сборщик мусора G1
Сборщик мусора G1 (Garbage First) предназначен для приложений, работающих на многопроцессорных машинах с большим объемом памяти. Он доступен с JDK 7 Update 4 и в более поздних выпусках.
G1 collector заменит CMS collector, так как он более эффективен с точки зрения производительности.
В отличие от других сборщиков, G1 сборщик разбивает кучу на набор областей кучи одинакового размера, каждая из которых представляет собой непрерывный диапазон виртуальной памяти. При выполнении сборки мусора G1 показывает параллельную глобальную фазу маркировки (т. Е. фазу 1, известную как Маркировка) для определения живучести объектов по всей куче.
После завершения фазы отметки G1 знает, какие области в основном пусты. Сначала он собирается в этих областях, что обычно дает значительное количество свободного пространства (т. Е. фаза 2, известная как Подметание). Именно поэтому этот метод сбора мусора называется “Сначала мусор”.
Чтобы включить сборщик мусора G1 , мы можем использовать следующий аргумент:
java -XX:+UseG1GC -jar Application.java
3.5. Изменения в Java 8
Java 8u20 ввела еще один параметр JVM для уменьшения ненужного использования памяти путем создания слишком большого количества экземпляров одной и той же строки . Это оптимизирует память кучи, удаляя дубликаты String значений в глобальный одиночный char[] массив.
Этот параметр можно включить, добавив -XX:+UseStringDeduplication в качестве параметра JVM .
4. Заключение
В этом кратком руководстве мы рассмотрели различные реализации Сборки мусора JVM и их варианты использования.
Более подробную документацию можно найти здесь .