- LeakCanary — канарейка для поиска утечек памяти
- Никому не нравятся ошибки с OutOfMemoryError
- Что такое утечка памяти?
- Охота на утечки
- Представляем LeakCanary
- Заключение
- Установка
- Русские Блоги
- LeakCanary с использованием подробного руководства (с демо)
- Свинец
- LeakCanary Введение
- Преимущества LeakCanary:
- Рабочий механизм LeakCanary:
- Интеграция LeakCanary в Android Studio
- LeakCanary прослушивает утечку памяти указанного объекта
- Страница отображения утечки памяти LeakCanary
- Разрешение утечки памяти
- Как использовать утечку канарейки
- ОТВЕТЫ
- Ответ 1
- Ответ 2
- Ответ 3
- Как использовать LeakCanary
- Как проверить исправление утечки памяти с помощью LeakCanary
- Ответ 4
LeakCanary — канарейка для поиска утечек памяти
Никому не нравятся ошибки с OutOfMemoryError
Работая над Square Register, мы рисовали подпись клиента, используя битмап-кэш. Поскольку этот битмап размером с экран устройства, у нас было очень много ошибок с переполнением памяти OutOfMemory (OOM).
Мы пробовали несколько подходов ни один из которых не решил проблему:
- Использовали Bitmap.Config.ALPHA_8 (подпись не требовала цвет)
- Ловили OutOfMemoryError, вызывали сборку мусора и пробовали снова (подглядели в GCUtils)
- Мы не рассматривали вариант с размещением битмапов вне кучи Java. К счастью Fresco еще не существовало
Мы шли по ложному пути.
Проблема была не в размере битмапа. Когда память почти полностью использована, OOM может возникнуть где угодно. Конечно, вероятность, что это произойдет во время выделения больших объектов, вроде битмапов, увеличивается. OOM — это лишь симптом более глубокой проблемы: утечек памяти.
Что такое утечка памяти?
Многие объекты имеют ограниченное время жизни. Когда их время жизни заканчивается, ожидаются, что они будут собраны сборщиком мусора. Если цепочка ссылок указывает на объект в памяти, после ожидаемого завершения времени жизни объекта, то это создаёт утечку памяти. При накоплении некоторого количества утечек, у программы начинает заканчивается память.
Например, после того как был вызван метод Activity.onDestroy, то активность и вся иерархия компонентов и связанные с ними битмапы должны быть доступны для сборки мусора. Если фоновый поток во время работы удерживает ссылку на активность, то занимаемая ей память не может быть освобождена. Рано или поздно это приведет к выбросу ошибки OutOfMemoryError.
Охота на утечки
Охота на утечки памяти — это ручной процесс, хорошо описанный в серии статей Wrangling Dalvik от Raizlabs.
Вот ключевые этапы:
- Узнать об ошибках OutOfMemoryError через Bugsnag, Crashlytics или консоль разработчика
- Попытаться воспроизвести проблему. Возможно вам понадобится купить, одолжить или украсть конкретное устройство, подверженное ошибке (Не на всех девайсах проявляются все утечки!). Также необходимо восстановить последовательность действий приводящих к утечке, возможно грубым перебором.
- Сделать дамп памяти при OutOfMemoryError (Здесь можно узнать как)
- Изучить дамп памяти с помощью MAT или YourKit и обнаружить объекты, которые должны были быть собраны сборщиком мусора
- Найти самые короткие пути ссыльных ссылок от объекта до корней сборщика мусора (GC Roots)
- Найти ссылку, которой не должно быть, и исправить утечку памяти
Что, если существовала бы библиотека, которая могла сделать это всё, ещё до возникновения OOM и позволила бы сосредоточится на исправлении утечки памяти?
Представляем LeakCanary
LeakCanary — это Java-библиотека с открытым исходным кодом для обнаружения утечек памяти в отладочных сборках.
Давайте взглянем на следующий пример:
Затем вы создаёте объект RefWatcher и предоставляете ему объект для отслеживания:
После того, как утечка была обнаружена, вы получаете неплохой трейс утечки.
Установка очень проста. С помощью всего одной строчки кода LeakCanary автоматически будет обнаруживать утечки активности:
Вы получаете уведомление в неплохом виде:
Заключение
После начала использования LeakCanary, мы обнаружили и исправили много утечек в нашем приложении. Мы даже нашли несколько утечек в Android SDK.
Результаты потрясающие: на 94% меньше ошибок с OutOfMemoryError!
Установи LeakCanary сейчас!
Установка
В файле build.gradle:
Эта запись означает, что проверка на утечку памяти будет происходить только во время разработки приложения, а в релизе и в тестах проверять ничего не надо.
В классе Application:
Готово! LeakCanary будет автоматически показывать уведомления при обнаружении утечки памяти.
LeakCanary.install() возвращает предварительно сконфигурированные RefWatcher. А также устанавливает ActivityRefWatcher, который автоматически определяет утечку после Activity.onDestroy().
Можно использовать RefWatcher для отслеживания утечек памяти у фрагментов:
Источник
Русские Блоги
LeakCanary с использованием подробного руководства (с демо)
Свинец
При оптимизации производительности Android оптимизация памяти является обязательным моментом, и наиболее важным моментом оптимизации памяти является решение проблемы утечек памяти. В Android также есть много инструментов анализа утечек памяти. Например, на стороне ПК есть: AndroidStudio поставляется с Android Profiler, MAT и другие инструменты, также доступные на мобильных телефонах, LeakCanary, которые мы собираемся представить сегодня
LeakCanary Введение
LeakCanaryЭто инструмент, предоставленный Square для разработчиков Android, для автоматического обнаружения утечек памяти.
LeakCanary — это инструмент с открытым исходным кодом для автоматического обнаружения утечек памяти в приложениях Android на основе MAT. Мы можем интегрировать пакет jar, предоставляемый LeakCanary, в наш собственный проект. После обнаружения утечки памяти LeakCanary просто сбрасывает информацию о памяти, анализирует и отображает информацию об утечке памяти с помощью другого процесса и может в любой момент найти и обнаружить проблему утечки памяти, вместо того чтобы каждый раз привлекать отдельного человека в процессе разработки для обнаружения проблемы утечки памяти. Облегчает разработку приложений для Android.
LeakCanary показывает страницы с утечками памяти:
Преимущества LeakCanary:
1. Полностью автоматизированная проверка утечки памяти для компонентов Android Activity.
2. Некоторые варианты поведения могут быть настроены (количество файлов дампа и объектов отслеживания утечек, пользовательские исключения, пользовательская обработка результатов анализа и т. д.).
3. Стоимость интеграции в ваш собственный проект и его использования очень низкая.
4. Дружественный интерфейс и отображение уведомлений.
Рабочий механизм LeakCanary:
котировкаLeakCanary китайские инструкцииЕго основной рабочий механизм заключается в следующем:
1. RefWatcher.watch () создает KeyedWeakReference для объекта, подлежащего мониторингу.
2. Затем проверьте, очищена ли ссылка в фоновом потоке, если нет, вызовите GC.
3. Если ссылка все еще не очищена, выведите дамп памяти кучи в файл .hprof в файловой системе, соответствующей приложению.
4. HeapAnalyzerService в другом процессе имеет HeapAnalyzer, использующий HAHA для анализа этого файла.
5. Благодаря уникальному ссылочному ключу HeapAnalyzer находит KeyedWeakReference и обнаруживает утечку памяти.
6. HeapAnalyzer вычисляет кратчайший путь с сильной привязкой к корням ГХ и определяет, является ли это утечкой. Если это так, создайте контрольную цепь, которая вызвала утечку.
7. Цепочка ссылок передается в DisplayLeakService в процессе APP и отображается в форме уведомления.
Интеграция LeakCanary в Android Studio
1. Добавьте пакет зависимостей LeakCanary в build.gradle. На данный момент последняя версия leakcanary — 1.6.1:
В разработке версии отладки и выпуска, как правило, интегрированы одновременно, из которых:
com.squareup.leakcanary: leakcanary-android: 1.6.1 является отладочной версией. Отладочная версия компилируется в вашем приложении и загружается пакет jar. Как только происходит утечка памяти, разработчик будет уведомлен в панели уведомлений о том, что произошла утечка памяти. ;
com.squareup.leakcanary: leakcanary-android-no-op: 1.6.1 — это версия выпуска. Если ваше приложение скомпилировано для версии выпуска, загружается пакет jar, а no-op означает, что операция не выполнена, что означает, что это не так. Будет выполнять любые операции и не будет мешать использованию обычных пользователей;
Зарегистрируйте LeakCanary в методе onCreate нашего пользовательского приложения.
- Объясните, почему вы должны судить LeakCanary.isInAnalyzerProcess (это) в первую очередь
Перед регистрацией определите, работает ли LeakCanary на вашем телефоне. Например, если у вас есть несколько приложений, интегрированных с LeakCanary одновременно, другие приложения уже запускают LeakCanary.
Давайте посмотрим на исходный код метода isInAnalyzerProcess:
Из исходного кода видно, что метод isInServiceProcess действительно вызывается. Взгляните на исходный код isInServiceProcess:
Мы можем видеть ComponentName component = new ComponentName (context, serviceClass);
Параметр serviceClass — это HeapAnalyzerService, вызываемый в методе isInAnalyzerProcess. HeapAnalyzerService — это отдельный процесс, используемый для анализа утечек памяти, поэтому LeakCanary требуется выполнить установку только на том же телефоне. Конечно, также возможно несколько казней;
- Возвращаясь к теме, при нормальных обстоятельствах после того, как приложение вызывает LeakCanary.install (это), оно может нормально отслеживать утечку памяти приложения;
LeakCanary прослушивает утечку памяти указанного объекта
Если вы хотите, чтобы LeakCanary прослушивал утечку памяти указанного объекта, нам нужно использовать функцию наблюдения RefWatcher следующим образом:
- Вызовите метод установки в Application onCreate и получите объект RefWatcher:
Примечание. Поскольку в данный момент вам необходимо получить объект sRefWatcher, необходимо выполнить sRefWatcher = LeakCanary.install (this), и вам не нужно оценивать LeakCanary.isInAnalyzerProcess (this)
- Чтобы упростить использование LeakCanary для получения и решения проблемы утечек памяти, мы сначала напишем сценарий утечки памяти.Мы знаем, что наиболее распространенной утечкой памяти является режим с одним столбцом, использующий контекст Activity, поэтому мы также используем режим с одним столбцом, чтобы продемонстрировать:
- В объекте, который должен прослушивать, вызовите метод watch из RefWatcher для прослушивания. Например, если я хочу прослушать Activity, мы можем добавить DemoApp.getRefWatcher (). Watch (this); в метод onCreate объекта Acitivity:
Страница отображения утечки памяти LeakCanary
В то же время, на вышеуказанных этапах, когда мы запускаем приложение, после того, как произошла утечка памяти, через короткий промежуток времени, мы будем уведомлены об утечке памяти в панели уведомлений:
В то же время на рабочем столе будет создан значок «Утечки», предназначенный для отображения списка утечек памяти. Страница со списком утечек памяти выглядит следующим образом:
Это список утечек памяти, мы можем нажать, чтобы увидеть содержимое утечки
Вы также можете нажать на знак «+» справа, чтобы просмотреть более подробную информацию. Если содержимое слишком длинное, снимок экрана не будет сделан. Внутри находится подробное описание процесса вызова.
Разрешение утечки памяти
В приведенной выше демонстрации мы использовали режим с одним столбцом для генерации утечки памяти. Конечно, мы знаем, как правильно устранить эту утечку памяти.
— это контекст приложения, когда Singleton singleton = Singleton.newInstance (this) передается в Contxt;
Вот краткое изложение общих сценариев и общих решений для утечек памяти
Распространенные сценарии утечки памяти:
Утечка 1.Memory вызванная картиной конструкции singleton
2. Утечка памяти, вызванная статическим экземпляром, созданным нестатическим внутренним классом
3. Утечка памяти, вызванная обработчиком
4. Утечка памяти из-за потоков
5. Утечка памяти из-за незакрытых ресурсов
Общие решения (идеи)
1. Попробуйте использовать контекст приложения вместо утечки активности
2. Используйте слабые или мягкие ссылки
3. Вручную установить ноль, утечка отношения разыменования
4. Установите для внутреннего класса значение static и неявно удерживайте утечки внешних экземпляров.
5. Регистрация и антирегистрация происходят парами, а операция антирегистрации выполняется в соответствующем жизненном цикле объекта. просачивание
6. Если у вас нет разрешения на изменение, например, системы или стороннего SDK, вы можете использовать отражение для разрешения отношений удержания.
7. После использования BraodcastReceiver, ContentObserver, File, Cursor, Stream, Bitmap и других ресурсов обязательно закройте, выйдите из системы или освободите память в OnDestry в Activity
Поскольку это слишком долго, мы не будем вводить это здесь.
Источник
Как использовать утечку канарейки
Я знаю, что это, наверное, немой вопрос, но я довольно новичок в разработке Android, и в настоящее время я испытываю OutOfMemoryError в своих приложениях, которые я пытался отлаживать с помощью MAT, но все равно слишком сложно найти утечку в нескольких действиях, тогда я нашел LeakCanary, который кажется более простым и простым в использовании, однако я не мог найти начального пошагового руководства по использованию Leak Canary даже в Google. Я установил LeakCanary через зависимости в моей build.gradle, и это то, что я получил до сих пор:
Скажем, у меня есть Activity, где я хочу, чтобы LeakCanary просматривал объект
Теперь, как я могу использовать LeakCanary, чтобы увидеть, какой объект вызывает утечку памяти. Благодарим вас за помощь и помощь.
ОТВЕТЫ
Ответ 1
Хорошая вещь о канале утечки — как автоматизировано это работает. По умолчанию он уже «наблюдает» за действиями, которые не соответствуют GCed. Поэтому из коробки, если какая-либо активность протекает, вы должны получить уведомление.
В моем проекте я добавил дополнительный метод для Application следующим образом:
поэтому важный материал с сборкой мусора и утечкой памяти и канарейкой должен знать, когда собирать материал и просить, чтобы этот элемент просматривался.
Например, мы используем «базовый фрагмент» со следующим кодом:
таким образом LeakCanary пытается проверить, не протекает ли какой-либо фрагмент памяти.
Итак, для дальнейшего внедрения в вашем приложении вы можете/должны выполнять задачи или экземпляры, которые, как вы знаете, должны собирать мусор, но вы думаете, что это может быть не так, и вы не знаете, где вы можете это назвать: ExampleApplication.instance.mustDie(object);
а затем вы ДОЛЖНЫ запускать приложение и поворачивать устройство и вызывать утечку, поэтому утечка canary может захватить/проанализировать трассировку стека и дать вам ценную информацию о том, как ее исправить.
Надеюсь, это поможет.
Ответ 2
Я использовал здесь в приложении
Вы можете использовать здесь Приложение вместо MultiDexApplication
Ответ 3
У меня был тот же вопрос о том, как использовать LeakCanary. Я просто хотел увидеть базовый пример того, как его запустить, и увидеть мой первый путь к утечке объекта.
Как использовать LeakCanary
Вот основной пример того, как работает LeakCanary:
Как использовать LeakCanary (4 минуты 13 секунд)
Одна из проблем, которую мне пришлось преодолеть, заключалась в том, чтобы выяснить, что мне нужно запускать приложение в обычном режиме запуска, а не в режиме отладки. Мне также пришлось отклониться от основных инструкций и установить файл build.gradle уровня build.gradle следующим образом:
Я думаю, что debugImplementation не работал для меня, потому что LeakCanary игнорирует обнаружение утечек при отладке. Хотя LeakCanary заявляет, что предоставляет версию «no-op» своей библиотеки для выпуска, так как отладка у меня не сработала, я изменил releaseImplementation выше с рекомендуемого com.squareup.leakcanary:leakcanary-android-no-op:1.5.4 в com.squareup.leakcanary:leakcanary-android:1.5.4 .
Как вы можете видеть на видео, еще одна проблема, с которой мне приходилось сталкиваться, заключалась в предоставлении доступа на запись в LeakCanary. Я провела пальцем вниз и увидела уведомление от LeakCanary о том, что не удалось получить доступ для записи (подробнее). Я никогда не видел запрос на разрешение. Таким образом, в одном случае (не показанном на видео) я дал своему приложению доступ на запись, перейдя в приложение «Настройки», найдя мое приложение (в отличие от приложения под названием «Leak», которое устанавливает LeakCanary) и включив доступ для записи. В видео мне не нужно было этого делать, потому что я дал разрешение, ответив на уведомление. Затем во время использования моего приложения я периодически проверяю наличие новых уведомлений (проводя вниз). Я видел сообщения типа «Утечка XYZActivity 217 КБ». Я нажал на это, и это заняло меня в этом приложении Leak.
Как проверить исправление утечки памяти с помощью LeakCanary
Теперь, когда я исправил некоторые утечки памяти, я использую LeakCanary для проверки исправления. Однако, если LeakCanary ничего не сообщает, я не обязательно верю в это, потому что моя утечка исправлена. Это может быть просто LeakCanary сломан.
Процесс проверки утечки памяти с помощью LeakCanary: 1. Подтвердите утечку памяти с помощью LeakCanary 2. Исправьте утечку памяти и подтвердите, что LeakCanary сообщает об отсутствии утечек 3. Отмените исправление и подтвердите, что LeakCanary снова сообщает об утечке
Поскольку LeakCanary показывает очень мало информации о состоянии, когда он работает, трудно понять, что он вообще делает. Это привело меня к мысли, что я исправил утечку памяти, а на самом деле я этого не сделал. Три шага, описанные выше, являются лучшим способом проверки утечки памяти с помощью LeakCanary.
Ответ 4
Я использовал Leak-Canary, как показано ниже:
1) Зависимость Gradle:
2) Класс применения:
3) Класс LeakLoggerService: поместите этот класс в пакет отладки, созданный gradle.
4) Зарегистрировать сервис для манифеста файла и 1 разрешение:
5) Наконец, проверьте, если установка прошла успешно: утечка активности;)
убить это действие и проверить журналы с тегом: LeakCanary
Источник