Что такое сборка мусора
Что проверяют
Понимаете ли вы, как освобождается память в Android-приложении и почему утечки случаются даже при автоматической сборке. Следом почти всегда спрашивают, как вы найдёте утечку Activity и что такое memory churn.
Как отвечать
Сборка мусора находит объекты, до которых нельзя дойти по ссылкам от корней, и освобождает их память. Корни (GC roots) это локальные переменные в стеках живых потоков, статические поля, JNI-ссылки. Счётчиков ссылок нет, поэтому циклические ссылки без внешнего владельца тоже собираются.
Дальше привяжите ответ к Android:
- ART вместо JVM: на устройствах работает Android Runtime, а не HotSpot. С Android 8 основной сборщик копирующий и работает параллельно с потоками приложения (concurrent copying), с Android 10 он ещё и поколенческий: молодые объекты собираются часто и дёшево;
- паузы: они короткие, но частые сборки всё равно отнимают процессор у главного потока и дают пропуски кадров;
- memory churn: создание объектов в горячих местах, например в
onDraw()илиonBindViewHolder(), провоцирует частые сборки. Лечится переиспользованием объектов; System.gc(): лишь просьба к рантайму, в рабочем коде её не вызывают;- утечка: объект достижим, но уже не нужен. Классика:
Activityв статическом поле или синглтоне, анонимныйHandlerилиRunnableс отложенным сообщением, неотписанный слушатель, ссылка наViewвоViewModel.
Инструменты: LeakCanary в debug-сборке, Memory Profiler в Android Studio и дамп кучи, где видна цепочка ссылок до корня.
Где спотыкаются
Говорят, что сборщик мусора исключает утечки. Он удаляет только недостижимое, а забытая ссылка на уничтоженную Activity держит в памяти весь её экран вместе с картинками.
Путают фазы Mark-and-Sweep. Помечаются живые объекты, достижимые от корней, а всё непомеченное считается мусором, не наоборот.
Предлагают WeakReference как универсальное лекарство. Она маскирует проблему владения; правильнее отвязывать ссылки по жизненному циклу, через onDestroy(), lifecycleScope или repeatOnLifecycle.