Какие типы ссылок есть в Kotlin и как ими управлять для контроля очистки памяти
Что проверяют
Знаете ли вы, что в Kotlin на JVM и в Android своих типов ссылок нет: это классы из java.lang.ref, и работают они по правилам сборщика мусора ART. На самом деле интервьюер выясняет, умеете ли вы предотвращать утечки Activity и Context. Следом спрашивают, как утечку найти.
Как отвечать
Назовите четыре вида ссылок и скажите, где каждый уместен:
- сильная: обычная ссылка
val user = User(). Пока объект сильно достижим от корней GC (статические поля, стеки потоков, JNI), его не соберут; WeakReference: не мешает сборке, после неёget()вернётnull. Подходит, когда долгоживущему объекту нужно сослаться на короткоживущий и не держать его;SoftReference: чистится при нехватке памяти. Документация Android прямо не советует строить на ней кеши: рантайм не знает, что дешевле, перезагрузить объект или держать его, поэтому для кеша берутLruCacheс явным размером;PhantomReference:get()всегда возвращаетnull, ссылка нужна, чтобы черезReferenceQueueузнать о недостижимости объекта и освободить внешний ресурс. Удобная обёртка над этим,Cleaner, в Android есть только на свежих версиях API.
Под «управлением» имеется в виду не выбор типа ссылки, а дисциплина жизненного цикла. Не кладите Activity, View и Fragment в статические поля и синглтоны, берите applicationContext, где контекст нужен надолго. Отписывайте слушатели в парном колбэке жизненного цикла. Корутины запускайте в viewModelScope или lifecycleScope, чтобы они отменялись вместе с экраном. Утечки ищите через LeakCanary (он сам построен на WeakReference и ReferenceQueue) и дамп кучи в профайлере Android Studio.
Где спотыкаются
Называют сильные, слабые, мягкие и фантомные ссылки «типами Kotlin». Это API Java, Kotlin ничего своего к нему не добавляет.
Советуют оборачивать всё в WeakReference «от утечек». Это маскирует ошибку в архитектуре: объект исчезает в неподходящий момент, а код обрастает проверками на null.
Описывают фантомную ссылку как указатель на уже собранный объект, из которого что-то можно достать. Достать нельзя ничего, это только сигнал о недостижимости.