Пример утечки памяти для Android из Google I/O

Я только что посмотрел на управление "памятью для Android" в google io. Слайды доступны здесь http://dubroy.com/memory_management_for_android_apps.pdf. Пример утечки памяти находится на слайде 36.

Я не понимаю, почему это вызывает утечку после изменения ориентации. Я понимаю, что утечка является внутренним классом и имеет ссылку на внешний класс. Кроме того, я понимаю, что статическая переменная "утечка" ссылается на объект "Leaky"... на всю деятельность. Я считаю это особенным из-за статического ключевого слова. Статические переменные имеют определенную память и, вероятно, не являются gc'ed (по крайней мере, пока приложение работает)?!?

Хорошо, что происходит при изменении ориентации? Создается новый экземпляр активности и вызывается деятельность onCreate. leak == null является ложным. Утечка все еще указывает на "старую" активность. Это утечка. Старая деятельность не может быть решена, верно?

Почему использование памяти увеличивается с каждым изменением ориентации? В моем (неправильном) понимании я бы предположил, что только первое действие не может быть gc'ed. Другие действия, которые создаются из-за изменения ориентации, могут быть записаны, потому что на них не ссылается эта статическая переменная "утечка".

Однако... очевидно. Я совершенно неправ!

Ответ 1

Классическое объяснение изменения ориентации. Утечка из контекстной памяти из Блог Google. По-моему, вы были в основном из-за статической ссылки внутреннего на внешний класс.

Ответ 2

Вы не понимаете, потому что сделали критическую ошибку. leak == null верен во вновь созданной активности. утечка не все еще указывает на "старую" активность.

Почему? Я думал, что утечка была статической, о которой вы спрашиваете. Что ж.,.

Итак, в первый раз, активность создается, утечка равна нулю, тогда onCreate() и утечка теперь ссылаются на объект Leaky. Если я создам больше экземпляров этого действия, их утечка не будет нулевой и ссылается на тот же объект.

Но, что происходит, когда вы переворачиваете ориентацию, это то, что действие уничтожено. Таким образом, нет существующего экземпляра объекта активности. Затем Android создает новую активность, где утечка равна нулю (поскольку в отношении Android не существует другого экземпляра активности).

Однако для сборщика мусора кто-то делает ссылку на разрушенную деятельность, а именно на ее внутренний класс Leaky. Поэтому он не освободит эту память. Следовательно, по мере того, как вы продолжаете менять ориентацию, вы продолжаете терять активность в памяти.