[Из песочницы] OutOfMemoryError. Боремся с утечками памяти в Android
В данной заметке мы рассмотрим несколько примеров утечек памяти в Android приложении. Также мы рассмотрим исправления этих утечек. Я хочу показать, что с утечками памяти можно и нужно бороться. Я не буду рассказывать про инструменты для анализа памяти, только лишь приведу ссылки на самые важные из них.
Для привлечения внимания к новому функционалу было принято решение воспользоваться анимацией. Необходимо было показать на короткий период View с подсказкой. Пример можно увидеть на изображении ниже:
Позже обнаружилась утечка Activity.
Проблема заключалась в том, что анимация fadeOut использовала слушателя от анимации fadeIn, что приводило к бесконечному запуску анимации fadeOut.
Исправить это было достаточно легко.
Анимации часто являются причинами утечек. Этого очень легко достигнуть забыв остановить бесконечную анимацию или запустив анимацию на неоправданно длительное время.
Бывает утечки памяти находятся и в самой платформе. Однажды я получил такой отчет:
Чтобы воспроизвести утечку достаточно создать Dialog с EditText внутри и что-нибудь в нем напечатать.
Как оказалось, это известный баг и он уже исправлен. Там же можно найти хак, для исправления этой утечки:
В одном из отчетов я получил утечку с не публичным, неизвестным мне ранее классом. Оказалось, что это приватный класс от одного популярного производителя.
На этот раз мне опять повезло и я нашел готовое решение в сети (1, 2).
В результате количество OutOfMemoryError уменьшилось почти в 7 раз. Так же уменьшилось количество RuntimeException, InflateException: часть из них — это пойманные и обернутые OutOfMemoryError. Одним из ограничивающих факторов в исправлении такого рода ошибок является то, что я не могу делать обновления, которые не содержат внешних изменений (для пользователей выглядит как «Пустое обновление») В таких случаях приходится ждать реализации нового функционала для проверки результатов.
- Документируйте не тривиальные/не очевидные моменты в коде, которые исправляют утечки памяти. Часто они выглядят подозрительно.
- Не ошибается тот, кто ничего не делает. Иногда приходится фиксить утечки памяти в чужом коде.
- Нужно знать свой инструментарий (hprof-conv, VisualVM, OQL, leakcanary)
- Обязательно делайте измерения и следите за ними (crash-report tools).
- Не допускайте увеличения количества ошибок.