С чего начать проектирование сборщика мусора (Garbage Collector)?

«С чего начать проектирование сборщика мусора (Garbage Collector)?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Проектирование начинается с анализа требований приложения: допустимые задержки (latency), пропускная способность (throughput) и использование памяти (memory footprint).

Основные этапы:

  1. Выбор алгоритма: mark-sweep, copying, generational, concurrent и т.д.
  2. Определение корней (GC Roots): стек потоков, статические поля, ссылки JNI.
  3. Реализация фазы пометки (mark): обход достижимого графа объектов.
  4. Реализация фазы очистки (sweep/compact/copy): освобождение или уплотнение памяти.

Пример упрощенного алгоритма Mark-Sweep:

void mark(Object obj) {
    if (obj == null || obj.isMarked()) return;
    obj.setMarked(true);
    for (Object ref : obj.getReferences()) {
        mark(ref); // Рекурсивный обход
    }
}

void sweep() {
    for (Object obj : heap) {
        if (!obj.isMarked()) {
            free(obj); // Освобождение памяти
        } else {
            obj.setMarked(false); // Сброс флага для следующего цикла
        }
    }
}

Критически важные аспекты для production-GC: минимизация stop-the-world пауз, параллелизм и безопасность для многопоточных сред.