Что такое достижимая и недостижимая ссылка в сборщике мусора
Что проверяют
Понимаете ли вы, по какому признаку сборщик мусора решает, что объект можно удалить, и связываете ли это с утечками памяти в Android. Следом почти всегда спрашивают, как утекает Activity и как это найти.
Как отвечать
Строго говоря, достижимым бывает объект, а не ссылка. Сборщик ART трассирующий: он начинает с корней (GC roots) и помечает всё, до чего можно дойти по цепочке ссылок. Корни это локальные переменные в стеках живых потоков, статические поля загруженных классов, глобальные JNI-ссылки и сами работающие потоки.
Объект без такой цепочки недостижим, его память можно вернуть, но момент сборки не гарантирован. Из-за трассировки циклы не проблема: два объекта, ссылающиеся друг на друга, соберутся, если снаружи на них ничто не указывает.
Дальше покажите градации из java.lang.ref:
- сильная ссылка: обычная, держит объект;
SoftReference: объект собирают при нехватке памяти. Для кешей в Android её не советуют, лучшеLruCacheс явным размером;WeakReference: не мешает сборке, объект уходит при ближайшем GC;PhantomReference: объект через неё не получить, она нужна, чтобы узнать о сборке и освободить внешние ресурсы.
Утечка в этих терминах это объект, который логически мёртв, но достижим. Классика: Activity в статическом поле или синглтоне, анонимный Runnable в Handler с задержкой, неотписанный listener, корутина в GlobalScope, binding во фрагменте, не обнулённый в onDestroyView(). Такие случаи находит LeakCanary: следит за уничтоженными экранами через слабые ссылки и, если после GC объект жив, снимает дамп кучи и показывает путь до корня.
Где спотыкаются
Считают, что obj = null или System.gc() освобождают память сразу. Первое убирает одну ссылку, второе для рантайма лишь подсказка.
Путают трассировку с подсчётом ссылок и говорят, что циклические ссылки текут. В Java и Kotlin на ART это не так.
Лечат утечки обёрткой всего подряд в WeakReference. Правильнее привязать работу к жизненному циклу: lifecycleScope, viewModelScope, отписка в парном колбэке.