← Назад к вопросам

Какие знаешь принципы работы Garbage Collector?

3.0 Senior🔥 121 комментариев
#JVM и управление памятью

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Принципы работы Garbage Collector в Java

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

Основные принципы работы GC

1. Generational Hypothesis (Гипотеза поколений)

JVM базируется на предположении, что большинство объектов живут недолго. Поэтому память делится на поколения:

  • Young Generation (молодое поколение): где создаются новые объекты
  • Old Generation (старое поколение): для долгоживущих объектов
  • Permanent Generation (постоянное) или Metaspace: для метаданных классов
Java Heap
├── Young Generation (1/3 heap)
│   ├── Eden Space
│   ├── Survivor Space 0
│   └── Survivor Space 1
└── Old Generation (2/3 heap)

2. Mark-Sweep-Compact алгоритм

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

Mark (Разметка): GC ходит от корневых ссылок и помечает все достижимые объекты.

// Пример: некоторые объекты достижимы
Object obj1 = new Object(); // помечен
Object obj2 = new Object();
obj2 = null; // не помечен - кандидат на удаление

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

Compact (Уплотнение): Оставшиеся объекты перемещаются, чтобы заполнить дыры в памяти и создать непрерывное пространство.

Типы сборок мусора

Minor GC (в Young Generation)

Бегает часто и быстро (обычно 10-100 мс):

1. Все новые объекты создаются в Eden Space
2. Когда Eden переполнится → Minor GC
3. Живые объекты копируются в Survivor Space
4. Мёртвые объекты удаляются

Major GC / Full GC (в Old Generation)

Бегает реже, но дольше (может быть несколько секунд):

1. Объекты из Young перемещаются в Old
2. Когда Old переполнится → Full GC
3. Mark-Sweep-Compact выполняется на всей куче
4. Паузы приложения (Stop-the-World) могут быть заметны

Алгоритмы сборки мусора

Serial GC (одноточечный)

Использует один поток для сборки. Хорошо для малых приложений.

java -XX:+UseSerialGC MyApp

Parallel GC (параллельный)

Использует несколько потоков, распределяя нагрузку. Лучше для многоядерных систем.

java -XX:+UseParallelGC MyApp
java -XX:ParallelGCThreads=4 MyApp

CMS (Concurrent Mark-Sweep)

Выполняет Mark и Sweep параллельно с приложением, минимизируя паузы.

java -XX:+UseConcMarkSweepGC MyApp

G1 GC (Garbage First)

Делит кучу на регионы и приоритизирует сборку областей с наибольшим количеством мусора. Рекомендуется для heap > 4GB.

java -XX:+UseG1GC MyApp
java -XX:MaxGCPauseMillis=200 MyApp  # макс пауза 200мс

ZGC и Shenandoah

Экспериментальные GC, имеющие паузы < 10мс даже для больших heap.

java -XX:+UseZGC MyApp

Признаки проблем с GC

Утечка памяти

// Плохо: объект остается в памяти навечно
public class EventListener {
    private static List<byte[]> cache = new ArrayList<>();
    
    public void onEvent(Event e) {
        cache.add(new byte[1024 * 1024]); // растет бесконечно
    }
}

Частые Full GC

Указывает на недостаточный heap или неэффективное использование памяти.

# Посмотреть GC логи
java -Xmx1024m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps MyApp

Мониторинг GC

JVisualVM (встроенный инструмент)

jvisualvm

Парсинг GC логов

java -Xmx512m -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:gc.log MyApp

Programmatic API

import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;

for (GarbageCollectorMXBean gc : ManagementFactory.getGarbageCollectorMXBeans()) {
    System.out.println("GC: " + gc.getName());
    System.out.println("Collection count: " + gc.getCollectionCount());
    System.out.println("Collection time: " + gc.getCollectionTime() + "ms");
}

Практические советы

  • Используй G1GC для heap > 4GB (по умолчанию в Java 9+)
  • Минимизируй создание объектов в критичных местах (циклы, обработчики событий)
  • Переиспользуй объекты через Object Pool, если создание дорого
  • Профилируй приложение перед оптимизацией GC
  • Избегай явных вызовов System.gc() — доверяй JVM
  • Мониторь heap размер: -Xms (минимум), -Xmx (максимум)
// Хорошая практика
public class ObjectPool {
    private Queue<StringBuilder> pool = new LinkedList<>();
    
    public StringBuilder acquire() {
        if (pool.isEmpty()) {
            return new StringBuilder();
        }
        return pool.poll();
    }
    
    public void release(StringBuilder sb) {
        sb.setLength(0); // очистить содержимое
        pool.offer(sb);
    }
}

Понимание GC критично для написания эффективного Java кода и диагностики проблем производительности в production.

Какие знаешь принципы работы Garbage Collector? | PrepBro