Найти в Дзене
Записки о Java

Как работает Garbage Collector в Java

Java славится своей автоматической управляемой памятью. Одним из ключевых механизмов, обеспечивающих стабильность и безопасность приложений, является Garbage Collector (GC) — система автоматической сборки мусора. В этой статье мы разберём: Garbage Collector (GC) — это часть Java Virtual Machine (JVM), которая автоматически освобождает память, выделенную под объекты, которые больше не используются. Он позволяет: Основной принцип: Корни (Roots) включают: Процесс сборки мусора состоит из нескольких этапов: 1. Mark Phase (Маркировка): GC проходит по всем объектам, начиная с корней, и помечает все достижимые объекты как живые. 2. Sweep / Compact / Copy Phase (Очистка / Уплотнение / Копирование): Sweep: Удаляются непомеченные (неживые) объекты. Compact: Живые объекты перемещаются в начало области памяти, чтобы избежать фрагментации. Copy: Объекты копируются из одной области в другую (например, из Eden в Survivor Space). Java делит память на несколько регионов: Young Generation (Eden Space +
Оглавление
Рисунок: Gabage Collector в Java
Рисунок: Gabage Collector в Java

Введение

Java славится своей автоматической управляемой памятью. Одним из ключевых механизмов, обеспечивающих стабильность и безопасность приложений, является Garbage Collector (GC) — система автоматической сборки мусора.

В этой статье мы разберём:

  • Что такое Garbage Collector
  • Как Java определяет, что объект больше не нужен
  • Как происходит сборка мусора
  • Как GC справляется с циклическими ссылками
  • Какие есть алгоритмы и стратегии сборки мусора

Что такое Garbage Collector?

Garbage Collector (GC) — это часть Java Virtual Machine (JVM), которая автоматически освобождает память, выделенную под объекты, которые больше не используются.

Он позволяет:

  • Избежать утечек памяти
  • Не заботиться о ручном освобождении памяти
  • Писать более надёжный код

Как Java понимает, что объект можно удалить?

Основной принцип:

  • Объект считается "живым", если он достижим из корневых объектов (roots) .

Корни (Roots) включают:

  • Локальные переменные методов
  • Активные потоки
  • Статические поля классов
  • JNI (Native) ссылки
  • Если объект не достижим ни от одного корня , он считается "мертвым", и Garbage Collector может его удалить.

Как происходит процесс сборки мусора?

Процесс сборки мусора состоит из нескольких этапов:

1. Mark Phase (Маркировка):

GC проходит по всем объектам, начиная с корней, и помечает все достижимые объекты как живые.

2. Sweep / Compact / Copy Phase (Очистка / Уплотнение / Копирование):

Sweep: Удаляются непомеченные (неживые) объекты.

Compact: Живые объекты перемещаются в начало области памяти, чтобы избежать фрагментации.

Copy: Объекты копируются из одной области в другую (например, из Eden в Survivor Space).

Где хранятся объекты в Java?

Java делит память на несколько регионов:

Young Generation (Eden Space + Survivor Spaces)

Old Generation (Tenured)

Metaspace (вместо PermGen в Java 8+)

Объекты сначала создаются в Eden Space , а затем, если они пережили несколько циклов GC, перемещаются в Old Generation .

Циклические ссылки и Garbage Collector

Циклические ссылки возникают, когда два или более объекта ссылаются друг на друга, но больше не доступны из корней .

Пример:

Рисунок: листинг примера циклической зависимости
Рисунок: листинг примера циклической зависимости

Может ли GC справиться с этим?

Да, может.

Поскольку оба объекта больше не достижимы из корней, даже несмотря на то, что они ссылаются друг на друга, Garbage Collector правильно удалит их .

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

Какие существуют алгоритмы сборки мусора?

Mark-Sweep (Маркировка-Очистка)

Помечает живые объекты и удаляет остальные. Может вызвать фрагментацию.

Mark-Sweep-Compact

То же самое, но после очистки уплотняет память.

Copying (Копирующий)

Перемещает живые объекты в новую область, быстро освобождает старую.

Generational Collection

Разделяет объекты по возрасту (молодые и старые). Используется по умолчанию в HotSpot JVM.

G1 Garbage Collector

Современный GC, работающий по регионально-ориентированному принципу. Хорош для больших объемов памяти.

ZGC / Shenandoah

Низколатентные GC для очень больших приложений (GB+ памяти).

Как выбрать подходящий Garbage Collector?

Выбор зависит от:

Размера приложения

Требований к производительности

Времени пауз (latency vs throughput)

Примеры параметров запуска:

  • # G1GC (по умолчанию в Java 9+)

java -XX:+UseG1GC MyApp

  • # Serial GC (для маленьких приложений)

java -XX:+UseSerialGC MyApp

  • # ZGC (низкая латентность, Java 11+)
  • java -XX:+UseZGC MyApp

Как увидеть работу Garbage Collector?

Добавьте JVM-флаги:

java -Xlog:gc*:file=gc.log:time MyApp

Или используйте:

  • VisualVM
  • JConsole
  • Mission Control (JMC)

Преимущества автоматической сборки мусора

  • Предотвращает утечки памяти
  • Автоматически управляет циклическими ссылками
  • Позволяет сосредоточиться на бизнес-логике
  • Поддерживает разные режимы работы (низкая задержка, высокая пропускная способность)

Когда стоит беспокоиться о GC?

  • Если наблюдаются длительные паузы (stop-the-world)
  • При частых Full GC
  • При OutOfMemoryError
  • При использовании большого количества временных объектов

Рекомендации

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

Заключение

Garbage Collector — это мощный инструмент, который делает Java одним из самых популярных языков программирования. Он умеет эффективно управлять памятью, в том числе справляться с такими сложными случаями, как циклические ссылки , без участия программиста.

Понимание того, как работает GC, поможет вам писать более качественный, быстрый и стабильный код, а также легко диагностировать проблемы с памятью.

Пример, рассмотренный в статье, можно найти по адресу:

https://github.com/ShkrylAndrei/blog_yandex/blob/main/src/main/java/info/shkryl/aboutGabageCollector/Main.java