Java for Beginner
675 subscribers
558 photos
156 videos
12 files
856 links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
Сборка мусора в Java

Сборка мусора (Garbage Collection, GC) — это автоматический процесс управления памятью, который освобождает объекты, больше не используемые программой. Главная задача GC — найти объекты, которые недостижимы, и освободить занимаемую ими память для повторного использования. Программистам в Java не нужно вручную управлять выделением и освобождением памяти (как, например, в языках C/C++), что значительно упрощает разработку и снижает количество ошибок, связанных с утечками памяти.

Память в Java разделена на две основные части: кучу (Heap) и стек (Stack). Объекты, создаваемые динамически (например, при вызове new), размещаются в куче и занимают определенное место до тех пор, пока они не станут недостижимыми. Если ненужные объекты не будут удаляться, память заполнится, что приведет к сбою программы из-за OutOfMemoryError.

Garbage Collector автоматически отслеживает и удаляет такие объекты, поддерживая память в чистоте и предотвращая утечки.

Основные концепции сборки мусора

Перед тем как погрузиться в детали, рассмотрим несколько ключевых понятий, связанных с управлением памятью в Java:

Достижимость объектов:
Объект считается достижимым, если на него есть ссылки из активных частей программы (например, глобальные переменные или переменные метода).
Недостижимый объект — это объект, на который нет ссылок, и он не может быть использован в дальнейшем.


Корни GC (GC Roots):
GC Roots — это специальные точки входа, от которых начинается проверка достижимости объектов.
Примеры GC Roots: активные потоки, статические поля классов, локальные переменные методов, ссылки из JNI (Java Native Interface).


Алгоритмы сборки мусора:
Существуют различные алгоритмы для отслеживания достижимости объектов: маркировка и удаление (Mark and Sweep), копирование (Copying), сжатие (Compaction) и другие.
Алгоритмы также могут отличаться по стратегии: минорная (Minor GC) и полная сборка (Full GC).


Молодое и старое поколения (Young и Old Generation):

Java-куча делится на несколько регионов:
Young Generation — область, в которой создаются новые объекты. В эту область чаще всего попадает сборка мусора.
Old Generation — сюда перемещаются более «долгоживущие» объекты. Сборка в этом регионе происходит реже, но является более затратной.


Как работает сборка мусора в JVM?

Java использует комбинацию разных алгоритмов и стратегий для эффективного управления памятью:

Mark and Sweep:
Основной алгоритм, используемый в большинстве JVM.
Маркировка (Mark): GC проходит по всем доступным объектам и помечает их как "достижимые".
Удаление (Sweep): Все объекты, которые не были помечены, удаляются.


Copying:
Этот алгоритм используется в Eden-области (молодое поколение).
Вся Young Generation делится на Eden и два Survivor пространства (From и To).
Когда Eden заполняется, GC перемещает все активные объекты в Survivor To область и очищает Eden.


Generational Garbage Collection:
JVM разделяет память на разные поколения:
Young Generation — для новых объектов.
Old Generation — для объектов, которые пережили несколько сборок.
Объекты перемещаются из Young в Old по мере увеличения их "возраста".


Compact and Defragmentation:
После удаления недостижимых объектов память может стать фрагментированной.
Для предотвращения фрагментации, GC может выполнять сжатие (compaction), перемещая объекты в соседние участки памяти.


#Java #Training #Medium #Garbage_collector
Типы сборок мусора в Java

JVM поддерживает несколько типов сборок мусора, каждый из которых предназначен для определенного типа приложений:


Serial GC:
Использует один поток для выполнения всех операций GC.
Подходит для однопоточных приложений или программ с небольшими кучами.


Parallel GC (или Throughput Collector):
Использует несколько потоков для сборки мусора.
Хорош для многопоточных приложений, стремящихся минимизировать время пауз.


CMS (Concurrent Mark-Sweep):
Предназначен для минимизации пауз при сборке мусора.
Выполняет маркировку и удаление объектов одновременно с выполнением программы.

Более ресурсоемкий и требует больше CPU.

G1 (
Garbage First):
Продвинутый сборщик, ориентированный на минимизацию пауз.
Делит память на множество регионов и выполняет сборку в приоритетных областях.


ZGC и Shenandoah:
Современные сборщики мусора с низкими паузами.
Ориентированы на большие кучи и высокую производительность.
Особенности сборки мусора в разных регионах памяти


Память в JVM делится на несколько регионов, каждый из которых имеет свои особенности:

Young Generation:
Основные области: Eden, Survivor From, Survivor To.
В этой области происходят минорные сборки (Minor GC) — сборки, которые удаляют недостижимые объекты в молодом поколении.


Old Generation:
Сюда попадают объекты, которые "пережили" несколько минорных сборок.
Сборка в этой области называется Full GC или Major GC и является более затратной по времени.


Permanent Generation (Metaspace):
Содержит метаинформацию, загружаемые классы и методы.
В более новых версиях JVM (с Java 8) эта область была заменена на Metaspace, которая динамически расширяется по мере необходимости.


#Java #Training #Medium #Garbage_collector
Внутреннее устройство Garbage Collector

Garbage Collector в Java работает на основе трех основных принципов:

Поиск недостижимых объектов.
Освобождение занимаемой ими памяти.
Компактизация и дефрагментация кучи (опционально, в зависимости от алгоритма).


1. Поиск недостижимых объектов
Каждый объект в Java находится в куче, и на него указывают ссылки (references). GC определяет объекты, которые больше не используются, с помощью концепции достижимости (Reachability). В JVM есть специальные точки, называемые корнями GC (GC Roots), от которых начинается проверка достижимости объектов.

Примеры GC Roots:
Локальные переменные и параметры метода.
Статические поля классов.
Ссылки из JNI (Java Native Interface).
Активные потоки.
Алгоритм маркировки и удаления (Mark and Sweep) проходит по GC Roots и помечает все объекты, до которых можно дотянуться. Недостижимые объекты (не помеченные) считаются кандидатами для удаления.


2. Освобождение памяти

После маркировки всех достижимых объектов начинается этап удаления. В зависимости от используемого GC, могут применяться разные стратегии удаления:
Сборка с переносом (Copying) — применимо в молодом поколении (Young Generation).
Удаление без компактизации — объекты удаляются, но места остаются фрагментированными.
Компактизация — память сжимается, перемещая все объекты в одну часть кучи.


3. Компактизация и дефрагментация

Когда объекты удаляются из памяти, в куче остаются «пустые» фрагменты, которые приводят к фрагментации. Некоторые GC, такие как G1 или Serial GC, выполняют компактизацию, чтобы переместить оставшиеся объекты и освободить непрерывный блок памяти. Компактизация полезна для улучшения производительности при выделении памяти новым объектам.

Виды Garbage Collector и их внутреннее устройство

Каждый сборщик мусора в JVM имеет свои особенности и алгоритмы, которые влияют на производительность и паузы приложения. Рассмотрим основные GC и их внутренние механизмы:

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


Parallel GC:
Многопоточная версия Serial GC.
Параллельно выполняет маркировку и удаление объектов.
Эффективно работает в многопроцессорных системах.


CMS (Concurrent Mark-Sweep):
Выполняет асинхронную сборку мусора, минимизируя паузы.

Этапы работы:
Initial Mark — быстрая маркировка активных объектов.
Concurrent Mark — параллельная маркировка всех достижимых объектов.
Concurrent Sweep — удаление недостижимых объектов.
Избегает компактизации, что может привести к фрагментации.


G1 GC (Garbage First):
Разделяет память на множество небольших регионов.
Выполняет параллельную сборку в приоритетных регионах.
Объединяет алгоритмы маркировки, удаления и сжатия.
Оптимизирован для минимизации пауз.


ZGC:
Сборщик мусора с нулевыми паузами.
Использует механизм цветной маркировки (Coloring) для управления памятью.
Работает на больших объемах памяти и в многопоточных приложениях.


Shenandoah:
Также минимизирует паузы за счет выполнения конкурентного перемещения объектов.
В отличие от ZGC, реализует дополнительные стратегии для снижения влияния на приложение.


#Java #Training #Medium #Garbage_collector
Внешнее управление сборщиком мусора

JVM предоставляет множество параметров, позволяющих управлять работой GC. Основные параметры включают:

Выбор алгоритма GC:
-XX:+UseSerialGC — включает Serial GC.
-XX:+UseParallelGC — включает Parallel GC.
-XX:+UseConcMarkSweepGC — включает CMS.
-XX:+UseG1GC — включает G1 GC.
-XX:+UseZGC — включает ZGC.


Настройка размеров памяти:
-Xms<size> — начальный размер кучи.
-Xmx<size> — максимальный размер кучи.
-XX:NewSize=<size> — размер молодого поколения.
-XX:MaxNewSize=<size> — максимальный размер молодого поколения.


Параметры управления метасферой (Metaspace):
-XX:MetaspaceSize=<size> — начальный размер метасферы.
-XX:MaxMetaspaceSize=<size> — максимальный размер метасферы.


Вывод информации о работе GC:

-XX:+PrintGCDetails — выводит детализированную информацию о сборках мусора.
-Xlog:gc* — в Java 9 и выше используется для логирования событий GC.
-XX:+HeapDumpOnOutOfMemoryError — создаёт дамп памяти при ошибке OutOfMemoryError.


Примеры управления GC с параметрами JVM

Допустим, у нас есть Java-приложение с высоким потреблением памяти. Мы хотим минимизировать паузы GC и эффективно использовать ресурсы.

Запуск с G1 GC и детальным логированием:
java -Xms2g -Xmx4g -XX:+UseG1GC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -XX:+PrintGCTimeStamps MyApp
Этот запуск включает G1 GC, устанавливает начальный размер кучи на 2 ГБ и максимальный на 4 ГБ, а также выводит подробные логи.


Диагностика и мониторинг работы GC


Понимание поведения сборщика мусора требует мониторинга его работы в реальном времени. Для этого существуют различные инструменты:

JVisualVM:
Графический инструмент для мониторинга памяти, потоков и GC.
Позволяет отслеживать метрики производительности и визуализировать сборки мусора.


JConsole:
Встроенный инструмент для мониторинга JVM.
Позволяет контролировать использование памяти, сборку мусора и состояние потоков.


GC Logs:
Логирование работы GC позволяет анализировать частоту и продолжительность сборок.
Для Java 8 и выше рекомендуется использовать параметр -Xlog:gc*.


JFR (Java Flight Recorder):
Мощный инструмент профилирования, который записывает метрики производительности, использование памяти и действия GC.
Запускается с параметром -XX:StartFlightRecording.


Пример анализа логов:
java -Xms1g -Xmx2g -XX:+UseG1GC -Xlog:gc:gc.log -XX:+PrintGCDetails MyApp
После выполнения мы можем открыть файл gc.log и проанализировать все события, связанные с GC, например, частоту минорных и мажорных сборок, продолжительность пауз и использование памяти.


Пример программы, создающей большое количество объектов, чтобы увидеть работу разных сборщиков мусора:
public class GCExample {
public static void main(String[] args) {
for (int i = 0; i < 10_000_000; i++) {
createObjects();
}
}

private static void createObjects() {
String[] strings = new String[1000];
for (int i = 0; i < strings.length; i++) {
strings[i] = new String("Object " + i);
}
}
}


Запустите эту программу с разными настройками GC, чтобы увидеть, как меняется поведение:
java -Xms512m -Xmx1g -XX:+UseG1GC -XX:+PrintGCDetails -XX:+PrintGCDateStamps GCExample


#Java #Training #Medium #Garbage_collector