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

С какой областью памяти работает Garbage Collector

2.3 Middle🔥 141 комментариев
#JVM и память#Производительность и оптимизация

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

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

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

🔍 Область памяти, управляемая Garbage Collector в Android (JVM/ART)

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

🧠 Структура кучи в контексте GC

В Android (на базе JVM/ART) куча разделена на несколько поколений, что оптимизирует работу сборщика мусора:

1. Young Generation (Молодое поколение)

  • Eden Space: Здесь создаются новые объекты
  • Survivor Spaces (S0 и S1): Сюда перемещаются выжившие объекты после сборки

2. Old Generation (Старое поколение)

Объекты, пережившие несколько сборок в Young Generation

3. Permanent Generation / Metaspace

  • В Java 7-: Permanent Generation (классы, метаданные)
  • В Java 8+: Metaspace (вне кучи, в нативной памяти)
// Пример: объекты в куче
public class UserData {
    private String name; // Ссылка и объект String - в куче
    private int age;     // Примитив - в стеке или внутри объекта в куче
    
    public UserData(String name, int age) {
        this.name = name; // Новый объект размещается в куче
        this.age = age;
    }
}

// Создание объекта - память выделяется в куче
UserData user = new UserData("Alex", 30);

⚙️ Что GC НЕ контролирует

Важно понимать границы ответственности GC:

  • Стек (Stack): Локальные переменные, вызовы методов (управляется автоматически)
  • Нативная память (Native Memory): Ресурсы через JNI, Bitmap пиксельные данные в Android API < 8
  • Memory Mapped Files: Прямое отображение файлов в память
  • Регистры процессора

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

Android Runtime использует несколько GC стратегий:

// Пример создания объектов разного времени жизни
fun memoryExample() {
    // 1. Краткоживущий объект (скорее всего в Young Gen)
    val tempList = mutableListOf<String>()
    repeat(1000) {
        tempList.add("item_$it")
    }
    // tempList станет мусором после выхода из функции
    
    // 2. Долгоживущий объект (может переместиться в Old Gen)
    companionObject = PersistentData()
    
    // 3. Утечка памяти - объект остается достижимым
    leakList.add(AnotherObject())
}

📊 Особенности работы GC в Android

Mark-and-Sweep с поколениями

// Упрощенная концепция алгоритма
1. Mark: Пометить достижимые объекты (от GC Roots)
2. Sweep: Удалить непомеченные объекты
3. Compact: (Опционально) Дефрагментация памяти

Stop-the-World паузы

Некоторые сборки требуют приостановки всех потоков приложения, что влияет на производительность.

🚀 Практические рекомендации

Оптимизация работы с памятью:

  1. Избегайте утечек памяти:
// Неправильно - анонимный класс держит ссылку на Activity
handler.postDelayed({
    updateUI() // Удерживает ссылку на внешний класс
}, 10000)

// Правильно - weak reference или очистка
private class SafeRunnable : Runnable {
    override fun run() {
        // Используем WeakReference
    }
}
  1. Используйте пулы объектов для часто создаваемых/удаляемых объектов

  2. Осторожно с большими объектами, которые могут попадать сразу в Old Generation

  3. Мониторинг памяти через Android Profiler

🎯 Ключевые выводы

  1. GC работает только с кучей (heap)
  2. Разделение на поколения оптимизирует производительность
  3. Разные алгоритмы для разных сценариев (Concurrent, CMS, G1)
  4. Понимание областей памяти критично для оптимизации производительности приложения

Начиная с Android 8 (API 26) ART использует конкурентный сборщик мусора (Concurrent GC), который значительно уменьшает Stop-the-World паузы, но принципиальная область работы — куча — остается неизменной.