Для определения утечки памяти в дампе (HPROF файле) используются инструменты, анализирующие граф объектов в куче. Основные шаги:
-
Получение дампа памяти:
- Через Android Studio Memory Profiler.
- Через команду
adb shell dumpheap <package_name> /data/local/tmp/dump.hprof.
- Через системный вызов
Debug.dumpHprofData(filePath).
-
Анализ дампа:
- Открытие дампа в Android Studio: В Memory Profiler или через меню "File" -> "Open".
- Анализ объектов: Сортировка объектов по размеру (Shallow Size, Retained Size) и количеству экземпляров.
- Поиск подозрительных объектов: Ищите классы, которые должны быть уничтожены (например, Activity, Fragment, Contexts) но имеют большое количество экземпляров или значительный
Retained Size.
- Изучение пути к объекту (Reference Chain): Выберите подозрительный объект и постройте его путь к корневым объектам (GC roots). Это покажет, кто именно держит ссылку, предотвращая сборку мусора.
- Поиск статических ссылок: Статические поля часто являются источником утечек, если хранят долгоживущие ссылки на контексты или View.
- Использование LeakCanary: Библиотека автоматизирует обнаружение, дамп и анализ утечек в рантайме, предоставляя подробное описание пути утечки.
-
Интерпретация результатов:
- Длинный путь к GC root, содержащий ссылки на объекты, которые должны быть уничтожены, указывает на проблему.
- Ссылки из статических полей, AsyncTask, Handler'ов с задержками, неправильно отписанных listeners/callbacks, или singleton'ов на активности или вью часто являются причиной утечек.
Пример анализа пути к GC root в Android Studio Memory Profiler:
plaintext
В этом примере анонимный класс (слушатель нажатия кнопки) держит неявную ссылку на MyActivity, хотя активность уже должна быть уничтожена (mDestroyed=true). Этот слушатель, видимо, где-то остается зарегистрированным или удерживается другим долгоживущим объектом (например, статическим полем или синглтоном).