Невидими лица (Android, управление на паметта), DOU
Дадено: Приложение за Android с аудитория от 10 милиона души. Crashlytics за проследяване на сривове.
Топ 1% сривове изглеждат така:

или дузина различни изгледи, но всички те са OutOfMemory сривове.
Беше извършена работа за анализ на съществуващите течове на памет в приложението и всички те бяха елиминирани. Щастието дойде, но беше за кратко. Имаше по-малко катастрофи, но не изчезнаха.

Изхвърляне на бедрата в инструмента за анализатор на паметта (www.eclipse.org/mat/)


Задача #4 - изпълнява се само една дейност. Но пукнатините не изчезнаха. Кара ме да мисля.
Хубаво е, че има умни хора в различни гугъли, които пишат умни статии като тази.
Да видим какво казва:
След минута стартиране на приложението с една отворена дейност в стека:

Еха! 560 гледания и 8 активности. Леле, по дяволите. нещо не е наред тук!
Започваме да разполовяваме кода в активността на живо.
Резултат:
1. Намерен код в стил:
време_в бъдеще_ДЕЙСТВИТЕЛНО_след затваряне_дейност);
Изглежда, че всичко е наред - ако активността е унищожена, нейните възгледи, които не се поддържат от нещо отвън, също трябва да бъдат унищожени, като предварително са почистени обратните извиквания. Но го нямаше. Този код причинява изтичане на цялата дейност. Той се третира или чрез преместване на runnable към член на класа и след това изтриването му, или чрез преместване на логиката към
с почистване във формата
в onDestroy или onStop. Въпреки че всъщност postDelayed на изгледа и манипулатора трябва да са еквивалентни, според уважавани хора в света на Android.
2. Преди известно време уважаван човек от хиндуистка националност прецака библиотека на трета страна, за да приложи блестящ ефект (светене върху текст). Нещо катоhttps://github.com/RomainPiel/Shimmer-android

Всичко работи перфектно. Няма видими лица. Следният код беше открит в кода на библиотеката:
Изглежда подозрително: - динамично задаване на стойностите на изгледа чрез отражение от някакъв делегат; - предаваме изгледа някъде в странно изглеждаща функция.
В кода на рамката в класа ObjectAnimator работата с изгледа изглежда безопасна:
Не трябва да има никакви течове.
В процеса на унищожаване на изследваната активност се извиква mAnimator.cancel(), което трябва да спре анимацията.
Шок: Анимацията НИКОГА не спира. Изпробвани са различни методи:
и други извращения. Нищо не помогна.
Нека модифицираме кода, за да се отървем от предаването на изгледа към аниматора. Ето! Изтичането на памет изчезна!
Точната причина, поради която аниматорът не спира, не е установена в нашия случай и е възможно други приложения да не страдат от това, но фактът е много неприятен.
Заключение: —Не вярвайте на очите си. Що се отнася до паметта, за съжаление различните инструменти показват различни неща и не знаете на какво да вярвате. - Изрично или косвено манипулиране на обекти на потребителския интерфейс на рамката (изгледи в нашия случай) обикновено е много лоша идея. - Когато разработвате приложения за Android, проверете изхода:
Очевидно това е единственият обективен източник на показатели на паметта и обекти на UI рамка, на които можете да разчитате, когато разработвате.