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

Что такое куча?

1.3 Junior🔥 121 комментариев
#JVM и память#Производительность и оптимизация

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

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

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

Что такое куча?

Куча (Heap) — это область памяти в JVM, используемая для динамического выделения памяти объектам во время выполнения программы. В отличие от стека, где хранятся примитивные типы и ссылки, куча содержит сами объекты.

Основные характеристики кучи

1. Динамическое выделение

  • Размер объектов неизвестен на этапе компиляции
  • Память выделяется во время выполнения
  • Может быть дефрагментирована

2. Управление памятью

  • Автоматическая очистка (Garbage Collection)
  • Объекты удаляются, когда на них нет ссылок
  • GC может вызвать задержки (jank) в Android приложениях

3. Общее пространство

  • Все потоки приложения обращаются к одной куче
  • Требуется синхронизация при многопоточности

Стек vs Куча

fun example() {
    // СТЕК: примитивы и ссылки на объекты
    val age: Int = 25              // int значение в стеке
    val name = "John"              // ссылка в стеке, строка в куче
    val user = User("John", 25)    // ссылка в стеке, объект в куче
    
    // Когда функция завершится:
    // - age, name, user будут удалены из стека
    // - Если нет других ссылок на объекты, они удалятся из кучи (GC)
}

Жизненный цикл объекта в куче

class User(val name: String, val age: Int)

fun main() {
    var user: User? = User("Alice", 30)
    // Шаг 1: Объект User создан в куче
    // Шаг 2: Переменная user содержит ссылку на объект
    
    user = null
    // Шаг 3: Ссылка удалена, объект становится доступен для GC
    // Шаг 4: Garbage Collector удалит объект из кучи (когда найдёт время)
}

Memory Leak пример

class AppActivity : Activity() {
    // ✗ ПЛОХО: утечка памяти
    companion object {
        var instance: AppActivity? = null
    }
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        instance = this  // Activity будет в памяти даже после destroy
    }
}

// ✓ ХОРОШО: правильный подход
class AppActivity : Activity() {
    private val viewModel: MyViewModel by viewModels()
    // ViewModel будет очищен вместе с Activity
}

Оптимизация работы с кучей в Android

1. Избегаем лишних объектов

// ✗ Плохо: создаёт новый список каждый раз
fun getUsers(): List<User> {
    return mutableListOf<User>().apply {
        // заполняем список
    }
}

// ✓ Хорошо: переиспользуем объект
private val userCache = mutableListOf<User>()
fun getUsers(): List<User> {
    return userCache
}

2. Управление ссылками

class MyViewModel : ViewModel() {
    // ✓ Правильно: weakReference для контекста
    private val context = WeakReference(context)
    
    // ✗ Неправильно: сильная ссылка на Context
    private val mContext = context
}

3. Монитор памяти

class MemoryMonitor {
    fun getHeapSize(): Long {
        val runtime = Runtime.getRuntime()
        val usedMemory = runtime.totalMemory() - runtime.freeMemory()
        return usedMemory
    }
}

Garbage Collection в Android

Этапы GC:

  1. Marking — определяет, какие объекты ещё используются
  2. Sweeping — удаляет неиспользуемые объекты
  3. Compaction — уплотняет память (опционально)

Время GC замораживает приложение, вызывая jank (задержки в UI).

Инструменты отладки

  • Android Profiler — визуализация использования кучи
  • Memory Profiler — детальный анализ утечек
  • LeakCanary — библиотека для обнаружения утечек памяти
  • Logcat — логирование GC событий

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

Для разработчика важно:

  1. Понимать, где объекты размещаются в памяти
  2. Избегать удержания больших объектов без необходимости
  3. Использовать слабые ссылки (WeakReference) для контекстов
  4. Закрывать ресурсы (try-with-resources, use блоки)
  5. Профилировать приложение на реальных устройствах

Куча — это сердце JVM памяти, понимание её работы критично для написания производительных Android приложений без утечек памяти.

Что такое куча? | PrepBro