Введение / Зачем это нужно
Утечка памяти — это распространённая проблема, которая медленно, но верно снижает производительность Android-устройств, вызывает задержки и accelerates разрядку батареи. Если не решать её, со временем приложение может аварийно завершиться из-за нехватки памяти.
В этом гайде вы узнаете, как быстро выявить основные причины утечек (неправильное управление жизненным циклом, статические ссылки, накопление объектов View) и устранить их с помощью встроенных инструментов Android Studio и популярной библиотеки LeakCanary. После выполнения инструкции вы сможете самостоятельно диагностировать и исправлять типичные утечки в своём коде.
Требования / Подготовка
- Android Studio (версия 2023.2 или выше).
- Устройство или эмулятор с включённой отладкой по USB.
- Android SDK Platform версии, соответствующей целевой API (например, API 33).
- Проект на Kotlin или Java (минимальная версия Gradle — 7.0).
Пошаговая инструкция
Шаг 1: Подключите устройство или эмулятор
Подключите Android-устройство через USB или запустите эмулятор в Android Studio. Убедитесь, что включено отладка по USB (Настройки → О телефоне → Номер сборки) и на компьютере установлен драйвер устройства.
Шаг 2: Запустите Android Profiler
В Android Studio откройте окно Profiler (View → Tool Windows → Profiler). Выберите своё устройство, перейдите во вкладку «Memory», нажмите «Record». Выполните действия в приложении, которые вызывают утечку, затем остановите запись.
Шаг 3: Используйте LeakCanary для автоматического обнаружения
Добавьте в проект зависимость leakcanary-android. В тестовом Activity или методе, где подозреваете утечку, создайте RefWatcher. Запустите тестовый запуск — LeakCanary покажет, какие объекты удерживаются дольше needed.
Шаг 4: Включите StrictMode для выявления сетевых операций
Добавьте в код следующее:
val strictModePolicy = object : StrictMode.ThreadPolicy.Builder()
.detectAll()
.penaltyLog()
.build()
StrictMode.setThreadPolicy(strictModePolicy)
Запустите приложение в режиме отладки; нежелательные сетевые операции или блокирующие вызовы будут отображаться в логах.
Шаг 5: Очистите кэш и перезапустите процесс
В настройках разработчика устройства откройте пункт «Очистить память приложения». Перезапустите приложение, чтобы убедиться, что временные данные не накапливаются повторно.
Шаг 6: Проанализируйте данные и внесите изменения
В окне Profiler изучите графики «Heap size» и «Allocated objects». Найдите объекты, которые остаются после завершения активности, удалите ненужные ссылки или используйте WeakReference. Перестройте код и повторите тест.
Проверка результата
После внесения изменений запустите приложение и повторите те же действия, которые ранее вызывали утечку. Откройте Profiler снова и убедитесь, что графики «Heap size» возвращаются к baseline значению после завершения работы. LeakCanary также должен перестать отображать обнаруженные утечки. Если проблемы сохраняются, проверьте статические коллекции, фоновые сервисы и корректность View‑связей.
Возможные проблемы
- Activity остаётся в памяти после переключения на другой экран – убедитесь, что вызываете
onDestroy/onPauseи очищаете ссылки (activity = null). - Статические списки удерживают объекты – используйте
WeakReferenceилиSparseArrayс правильным управлением жизненным циклом. - LeakCanary не работает в продакшене – библиотека отключена в release-сборках; используйте для тестирования или эмуляции.
- StrictMode генерирует много логов – ограничьте его определёнными нарушениями (
detectNetwork(),detectCustomSlowCalls()) для фокуса на критичных проблемах.
Если эти советы не помогают, проверьте использование WorkManager и фоновых служб, особенно на устройствах под Android 12+, где stricter ограничения на фоновую работу могут имитировать утечки.