Middle+
180
questionbank
Как определить наличие утечки памяти при анализе дампа?
Answer from AI
sobes.tech AI
Для определения утечки памяти в дампе (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:
// Пример пути к GC root, указывающий на утечку
// android.app.Activity instance with mDestroyed=true
// references android.widget.LinearLayout instance
// references android.view.View $ListenerInfo instance
// references com.example.MyActivity$1 instance (Anonymous class implementing View.OnClickListener)
// references com.example.MyActivity instance (Leaking this reference)
В этом примере анонимный класс (слушатель нажатия кнопки) держит неявную ссылку на MyActivity, хотя активность уже должна быть уничтожена (mDestroyed=true). Этот слушатель, видимо, где-то остается зарегистрированным или удерживается другим долгоживущим объектом (например, статическим полем или синглтоном).