ANR & Memory Management Interview Questions
PERFORMANCE › Runtime
Walk me through how you'd debug an ANR that only reproduces on a specific low-end device model in production, when you can't repro it locally.
What a strong answer covers: A strong answer leans on ApplicationExitInfo (getHistoricalProcessExitReasons) to pull the ANR trace from the actual affected process after the fact, plus Play Console's ANR reports and Android Vitals, since local repro on a low-end device is unlikely. Should reason about device-specific culprits: slower storage/I/O turning a disk read that's fine on a flagship into a main-thread block past 5s, fewer cores worsening lock contention, or lower memory triggering more aggressive GC pauses that add up to the timeout.
When would you reach for a WeakReference instead of just fixing the underlying lifecycle or ownership issue? What's the risk of using WeakReferences as a band-aid for leak-prone code?
What a strong answer covers: A WeakReference fits caches or observer lists where holding the referent slightly longer than needed is acceptable and being cleared unpredictably by the GC is fine, but it's not a substitute for correct lifecycle ownership because the object can be collected at any GC pass, not deterministically when the screen is destroyed, leading to non-deterministic crashes or silently dropped callbacks. A strong answer flags that reaching for WeakReference to 'fix' a leak without understanding why the strong reference existed is a smell; the right move is usually breaking the reference in onDestroy/onCleared or restructuring ownership.
Your memory profiler shows a sawtooth pattern with a rising floor over time, not a hard leak. What's actually happening, and how do you distinguish 'this is just GC doing its job' from 'this is a slow leak'?
What a strong answer covers: A sawtooth with a flat floor between GC cycles is normal allocation and collection churn; a floor that trends upward across multiple GC cycles, even after forcing a GC, means objects are being retained that shouldn't be, i.e. an actual leak. A strong answer describes confirming this by repeating a navigate-in/navigate-out cycle on a screen while watching whether retained heap after GC returns to baseline, and pulling a heap dump or using LeakCanary to identify what's pinning the growing objects if it doesn't.