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

Что произойдет когда закончится память в Heap?

1.0 Junior🔥 52 комментариев
#Опыт и софт-скиллы

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

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

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

Механизм работы с исчерпанием памяти в куче (Heap)

Когда память в куче (Heap) подходит к концу, система Android запускает сложную цепочку событий, направленную на освобождение ресурсов и предотвращение краха приложения. Этот процесс тесно интегрирован с сборщиком мусора (Garbage Collector, GC) и системой управления памятью.

Фазы реакции системы на нехватку памяти

1. Запуск сборки мусора (Garbage Collection)

Первая и основная линия обороны — активация сборщика мусора. В современных Android (ART, Android Runtime) используется несколько поколений GC:

// Пример: создание объектов, которые могут быть собраны
fun createGarbage() {
    val temporaryList = mutableListOf<String>()
    repeat(1000) {
        temporaryList.add("Item $it") // Создаются объекты в куче
    }
    // После выхода из функции temporaryList становится недостижимым
    // и может быть удален сборщиком мусора
}

Сборщик мусора проходит через корневые объекты (GC Roots) и помечает все достижимые объекты. Все непомеченные объекты считаются мусором и удаляются. Однако если после сборки свободной памяти всё ещё недостаточно, система переходит к более агрессивным мерам.

2. Увеличение размера кучи (Heap Expansion)

В некоторых случаях ART может попытаться временно увеличить размер кучи за счет резервных ресурсов системы, если это позволяет конфигурация устройства и текущая нагрузка. Однако это временная мера, так как физическая память устройства ограничена.

3. Вызов onTrimMemory() и onLowMemory()

Система отправляет callback-уведомления компонентам приложения:

class MainActivity : AppCompatActivity() {
    override fun onTrimMemory(level: Int) {
        super.onTrimMemory(level)
        when (level) {
            ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE -> {
                // Начало нехватки памяти
                releaseCachedResources()
            }
            ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL -> {
                // Память почти исчерпана
                releaseAllNonCriticalResources()
            }
            ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN -> {
                // UI скрыт, можно освободить ресурсы интерфейса
            }
        }
    }
    
    private fun releaseCachedResources() {
        // Очистка кэшей изображений, данных и т.д.
        imageCache.evictAll()
    }
}

4. Принудительное завершение процессов

Если предыдущие шаги не помогают, ActivityManager начинает останавливать процессы по приоритетам (Least Recently Used - LRU):

  • Фоновые процессы без видимых Activity
  • Сервисные процессы с наименьшим приоритетом
  • Видимые процессы (редко)
  • Процессы переднего плана (только в крайних случаях)

Последствия для приложения разработчика

  1. OutOfMemoryError (OOM) – если приложение исчерпало выделенную ему квоту памяти и система не может её увеличить, выбрасывается исключение:
// Типичный сценарий OOM
try {
    Bitmap largeBitmap = BitmapFactory.decodeFile(hugeImagePath);
} catch (OutOfMemoryError e) {
    // Обработка ошибки: уменьшение размера изображения, 
    // использование inSampleSize и т.д.
    val options = BitmapFactory.Options()
    options.inSampleSize = 4 // Уменьшение в 4 раза
    val reducedBitmap = BitmapFactory.decodeFile(hugeImagePath, options)
}
  1. Производительность – частые сборки мусора вызывают задержки (GC Pauses), что приводит к дропу кадров, лагам интерфейса и плохому UX.

  2. Стабильность – приложение может быть завершено системой без возможности восстановления состояния.

Стратегии предотвращения проблем

Мониторинг использования памяти

// Отслеживание использования памяти
val runtime = Runtime.getRuntime()
val usedMemory = runtime.totalMemory() - runtime.freeMemory()
val maxMemory = runtime.maxMemory()
val memoryUsagePercent = usedMemory.toFloat() / maxMemory.toFloat() * 100

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

  • Использование пулов объектов для часто создаваемых/удаляемых объектов
  • Оптимизация Bitmap: inSampleSize, inBitmap, форматы RGB_565
  • Своевременное освобождение ресурсов (Closeable, регистрация/отмена BroadcastReceiver)
  • Анализ утечек памяти с помощью LeakCanary или Android Studio Profiler

Рекомендации по архитектуре

  • ViewModel для хранения данных, связанных с UI
  • Paging Library для работы с большими наборами данных
  • Использование слабых ссылок (WeakReference) для кэшей

Система Android предоставляет инструменты для управления памятью, но ответственность за эффективное использование ресурсов лежит на разработчике. Правильная обработка событий нехватки памяти и профилактические меры позволяют создавать стабильные приложения даже на устройствах с ограниченными ресурсами.

Что произойдет когда закончится память в Heap? | PrepBro