В данной заметке мы рассмотрим несколько примеров утечек памяти в Android приложении. Также мы рассмотрим исправления этих утечек. Я хочу показать, что с утечками памяти можно и нужно бороться. Я не буду рассказывать про инструменты для анализа памяти, только лишь приведу ссылки на самые важные из них.
Неправильный AnimationListener
Для привлечения внимания к новому функционалу было принято решение воспользоваться анимацией. Необходимо было показать на короткий период View с подсказкой. Пример можно увидеть на изображении ниже:
Позже обнаружилась утечка Activity.
Проблема заключалась в том, что анимация fadeOut использовала слушателя от анимации fadeIn, что приводило к бесконечному запуску анимации fadeOut.
Исправить это было достаточно легко.
Анимации часто являются причинами утечек. Этого очень легко достигнуть забыв остановить бесконечную анимацию или запустив анимацию на неоправданно длительное время.
android.widget.Editor$Blink
Бывает утечки памяти находятся и в самой платформе. Однажды я получил такой отчет:
Чтобы воспроизвести утечку достаточно создать Dialog с EditText внутри и что-нибудь в нем напечатать.
Как оказалось, это известный баг и он уже исправлен. Там же можно найти хак, для исправления этой утечки:
Утечка от производителя. Singleton — зло
В одном из отчетов я получил утечку с не публичным, неизвестным мне ранее классом. Оказалось, что это приватный класс от одного популярного производителя.
На этот раз мне опять повезло и я нашел готовое решение в сети (1, 2).
Результаты
В результате количество OutOfMemoryError уменьшилось почти в 7 раз. Так же уменьшилось количество RuntimeException,InflateException: часть из них — это пойманные и обернутые OutOfMemoryError. Одним из ограничивающих факторов в исправлении такого рода ошибок является то, что я не могу делать обновления, которые не содержат внешних изменений (для пользователей выглядит как “Пустое обновление”) В таких случаях приходится ждать реализации нового функционала для проверки результатов.
Выводы
- Документируйте не тривиальные/не очевидные моменты в коде, которые исправляют утечки памяти. Часто они выглядят подозрительно.
- Не ошибается тот, кто ничего не делает. Иногда приходится фиксить утечки памяти в чужом коде.
- Нужно знать свой инструментарий (hprof-conv, VisualVM, OQL, leakcanary)
- Обязательно делайте измерения и следите за ними(crash-report tools).
- Не допускайте увеличения количества ошибок.
Ссылки
- VisualVM visualvm.java.net
- OQL visualvm.java.net/oqlhelp.html
- leakcanary github.com/square/leakcanary
- Исходный код примеров github.com/kurganec/leak_examples
ссылка на оригинал статьи http://habrahabr.ru/post/272775/
Добавить комментарий