ANR & Memory Management Flashcards

PERFORMANCE › Runtime

What are the main ANR timeout thresholds?
Input/key dispatch blocked for 5s; foreground BroadcastReceiver.onReceive() over 10s (background 60s); foreground Service lifecycle over 20s (background 200s); startForegroundService without startForeground() within 5s.
What fundamentally causes an ANR?
The main (UI) thread is blocked too long to process input or component lifecycle in time. Common reasons: slow I/O or computation on the main thread, lock contention, deadlocks, or synchronous binder calls to another process.
How do you move long work off the main thread on modern Android?
Use Kotlin coroutines on Dispatchers.IO or Default and post results back to the main dispatcher, or WorkManager for deferrable/guaranteed work. AsyncTask is deprecated. Use StrictMode to catch accidental main-thread I/O.
A BroadcastReceiver needs work that may exceed 10 seconds. How do you avoid an ANR?
Don't block onReceive(). Call goAsync() to get a PendingResult, do the work on a background thread, then call finish(); or hand off to WorkManager/JobScheduler. onReceive() itself must stay short.
Why does holding an Activity (or its Context/View) in a static field leak memory?
The static field outlives the Activity, so after onDestroy the GC can't reclaim the Activity or its entire view tree. Use applicationContext for long-lived needs, or null out the reference.
Why do non-static inner classes like Handlers, Runnables, or AsyncTask leak, and how do you fix it?
A non-static inner class holds an implicit reference to its outer Activity; if its queued/running work outlives the Activity, the Activity can't be collected. Fix: make it static and hold the Activity via a WeakReference, and remove pending messages/callbacks in onDestroy.
How do unregistered listeners or receivers cause leaks?
Registering a listener, BroadcastReceiver, sensor, or observer (often with an Activity as callback) without unregistering keeps the subject holding the Activity reference. Always pair register in onStart/onResume with unregister in onStop/onDestroy, or use lifecycle-aware components.
WeakReference vs SoftReference: when is each cleared?
A WeakReference is cleared at the next GC once the referent is only weakly reachable. A SoftReference is retained until the heap is under memory pressure (just before OutOfMemoryError), making it suitable for a memory-sensitive cache.
What causes OutOfMemoryError with bitmaps, and how do you prevent it?
Each app has a hard heap cap; exceeding it throws OOM. Bitmaps are usually the largest objects: a 1000x1000 ARGB_8888 bitmap is ~4MB (1,000,000 px x 4 bytes). Downsample with inSampleSize or use a loader (Coil/Glide), release on onTrimMemory, and find leaks with LeakCanary or the Memory Profiler.

Back to ANR & Memory Management