Beyond LeakCanary, Android provides several complementary tools for diagnosing memory issues at different granularities: the Android Studio Memory Profiler for interactive investigation,Documentation Index
Fetch the complete documentation index at: https://mintlify.com/AmolPardeshi99/android-performance-skills/llms.txt
Use this file to discover all available pages before exploring further.
adb shell dumpsys meminfo for quick field checks, adb shell am dumpheap for CI-automated heap dumps, Perfetto for production-grade profiling, and ApplicationExitInfo for post-mortem OOM detection.
Android Studio Memory Profiler
The Memory Profiler is the best tool for interactive investigation. It shows live memory allocation, lets you force a GC, and captures a heap dump that you can navigate in the IDE.Run the app in Profile mode
In Android Studio, select Run → Profile (or click the profile icon). This launches the app with profiling agents attached.
Navigate between screens multiple times
Open and close the screens you want to investigate. Repeated navigation amplifies leaks, making them easier to spot as a rising memory baseline.
Force a garbage collection
Click the GC bucket icon in the Memory Profiler toolbar to trigger a full GC. Legitimate objects will be collected; leaked objects will remain.
Capture a heap dump
Click Capture Heap Dump. Android Studio captures an HPROF snapshot of the current heap.
Filter for Activity and Fragment leaks
In the heap dump view, use Filter → Show Activity/Fragment leaks to surface destroyed instances that are still in memory.
adb shell dumpsys meminfo
dumpsys meminfo provides a fast snapshot of the memory state of your app — no IDE required. It is useful for quick checks on physical devices in the field.
adb shell am dumpheap
am dumpheap produces an HPROF heap dump via the shell, with no IDE attachment needed. This makes it suitable for CI pipelines, automated test runs, and devices without USB debugging UI.
Convert to Android Studio-compatible format
The raw HPROF from the device must be converted before Android Studio can open it:
Perfetto + heapprofd
Perfetto is the production-grade profiling platform for Android.heapprofd hooks into the allocator and samples Java and native heap allocations continuously — without recompiling the app — making it suitable for profiling on user builds with debuggable=true.
ApplicationExitInfo — post-mortem OOM detection
ApplicationExitInfo (API 30+) records the reason for each process termination, including out-of-memory kills. Query it at startup to surface OOM events that happened in previous sessions — events that would otherwise be invisible.
description and timestamp to your crash reporting backend so you can correlate OOM kills with app version, device model, and session data.
Code review checklist
View-based system checklist
View-based system checklist
- Every Fragment with ViewBinding nulls
_bindinginonDestroyView - No Activity, Fragment, View, or Binding stored in ViewModel, singleton, or companion object
- All singletons and long-lived objects use
applicationContext, not Activity context - Every listener/observer/receiver registration has a symmetric unregister in the paired lifecycle method
-
ConnectivityManager.CONNECTIVITY_ACTIONnot used (deprecated API 28+) — useNetworkCallback - LiveData observed with
viewLifecycleOwner(notthis) in Fragments - Flow collected inside
repeatOnLifecycle(STARTED)block - No
GlobalScope.launchin any production code - All Cursor, InputStream, OutputStream, MediaPlayer, DB connections use
use {} - Handler
postDelayedrunnables have matchingremoveCallbacksin teardown - Custom Views release animators, bitmaps, and listeners in
onDetachedFromWindow - Custom Views call
TypedArray.recycle()(oruse {}) ininit {}— always infinally -
registerForActivityResultcalled at Fragment/Activity construction time, not inonViewCreated -
NavController.addOnDestinationChangedListenerpaired withremoveOnDestinationChangedListenerinonDestroyView -
by lazy {}in Fragment does not capturethis— usesapplicationContextor deferred init pattern -
Choreographer.postFrameCallbackhas matchingremoveFrameCallbackinonPause/onDestroyView -
ProcessLifecycleOwnerobservers use only application-scoped objects — never Activity/Fragment instances - Services call
stopSelf()on task completion; WorkManager preferred over long-running services - WebView hosted in a separate process via
android:process - LeakCanary in debug builds; zero leaked signatures suppressed without documented justification
- Hilt / DI scope annotations match the actual lifetime of each dependency
- LeakCanary 2.14 in debug builds with
DetectLeaksAfterTestSuccessrule in UI tests -
adb shell dumpsys meminfoActivity count checked after navigation — drops to 1 after Back - Heap dump captured via
adb shell am dumpheapor Memory Profiler after repeated navigation -
ApplicationExitInfoqueried at startup to detectREASON_LOW_MEMORYexits in production