Сборщик мусора (Garbage Collection, GC) — это механизм в Java, который автоматически управляет памятью, освобождая её от объектов, которые больше не используются в программе. Это одна из ключевых особенностей Java, которая избавляет разработчиков от необходимости вручную управлять памятью, как это делается, например, в языках вроде C или C++.
В Java память делится на две основные области:
Сборщик мусора работает с кучей (Heap), освобождая память от объектов, которые больше не доступны.
Каждый объект в Java создается в куче, и на него ссылаются переменные в стеке или другие объекты. Если на объект больше нет ссылок, он становится недостижимым (unreachable) и может быть удален сборщиком мусора.
Сборщик мусора начинает свою работу с поиска всех достижимых (reachable) объектов. Достижимыми считаются объекты, на которые есть ссылки из стека или из других достижимых объектов. Все остальные объекты считаются недостижимыми и подлежат удалению.
В Java используется несколько алгоритмов сборки мусора, которые могут быть настроены в зависимости от требований приложения. Основные из них:
Mark and Sweep (Пометка и очистка):
Generational Garbage Collection (Поколенческая сборка мусора): Куча делится на несколько областей (поколений):
В Java доступны различные реализации сборщиков мусора, каждая из которых оптимизирована для разных сценариев:
public class GarbageCollectionExample {
public static void main(String[] args) {
// Создаем объект
Object obj1 = new Object();
// Указываем на новый объект, старый становится недостижимым
obj1 = new Object();
// Вызываем сборщик мусора (не гарантирует немедленное выполнение)
System.gc();
}
@Override
protected void finalize() throws Throwable {
System.out.println("Объект удален сборщиком мусора.");
}
}
obj1
.obj1
начинает ссылаться на новый объект, старый объект становится недостижимым.System.gc()
рекомендует JVM выполнить сборку мусора, но это не гарантирует её немедленное выполнение.finalize()
вызывается перед удалением объекта (если он переопределен).Понимание работы сборщика мусора важно для написания эффективных и производительных Java-приложений, особенно в системах с большими объемами данных и строгими требованиями к производительности.