Утечки памяти

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

class MyActivity : AppCompatActivity() {
    private val myListener = MyListener()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Регистрация слушателя
        MySingleton.addListener(myListener)
    }

    override fun onDestroy() {
        super.onDestroy()

        // Утечка памяти: не удаляем ссылку на слушателя
        // MySingleton.removeListener(myListener)
    }
}

object MySingleton {
    private val listeners = mutableListOf<MyListener>()

    fun addListener(listener: MyListener) {
        listeners.add(listener)
    }

    fun removeListener(listener: MyListener) {
        listeners.remove(listener)
    }
}

class MyListener {
    // Обработчик событий
}

В этом примере MyActivity регистрирует экземпляр MyListener в MySingleton в методе onCreate(), но забывает удалить ссылку на него в методе onDestroy(). Это приведет к тому, что MyListener будет продолжать существовать после уничтожения MyActivity, что может привести к утечке памяти.

Как избежать утечек памяти

Использование слабых ссылок (Weak References) и мягких ссылок (Soft References)

val weakReference = WeakReference<MyObject>(myObject)
val softReference = SoftReference<MyObject>(myObject)

Освобождение ресурсов вовремя:

Убедитесь, что все ресурсы, такие как файлы, базы данных, потоки и т. д., закрываются или освобождаются вовремя. Используйте блоки try-finally или use для гарантированного закрытия ресурсов после их использования.

Избегайте статических ссылок на контекст:

Избегайте использования статических ссылок на активности или контекст приложения, так как они могут привести к утечкам памяти. Вместо этого, используйте слабые ссылки или передавайте контекст как параметр, когда это необходимо.

Освобождение ресурсов в onDestroy():

В методе onDestroy() активности или фрагмента убедитесь, что все ресурсы освобождаются. Например, отмените все запросы к сети, отмените регистрацию слушателей и т. д.

Используйте профилировщики памяти:

Используйте инструменты профилирования памяти, такие как Android Profiler или LeakCanary, чтобы обнаруживать утечки памяти в рантайме и исправлять их.

dependencies {
    debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.7'
}
class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        if (LeakCanary.isInAnalyzerProcess(this)) {
            return
        }
        LeakCanary.install(this)
    }
}