Coroutines make asynchronous programming easy, but they can easily lead to memory leaks if launched in a scope that survives past the lifecycle of the UI component using it. A common mistake is using GlobalScope for everything.

The Danger of GlobalScope

If you launch a coroutine in GlobalScope, it lives as long as the entire application. If it references an Activity or Fragment, it will prevent that component from being garbage collected even after being closed.

The Leaky Way GlobalScope.launch {
val data = fetchData() // Survivors forever if not canceled!
updateUI(data)
}

The Modern Solution

Use lifecycle-aware scopes provided by the Android Architecture Components. viewModelScope in ViewModels and lifecycleScope in Fragments/Activities automatically cancel all running coroutines when the component is destroyed.

The Safe Way viewModelScope.launch {
val data = fetchData()
_state.value = data // Automatically canceled onCleared()
}

Summary

Avoid GlobalScope like the plague. Use lifecycle-aware scopes to ensure your background tasks die when they're no longer needed. Cleaner code, better performance!