How to Identify a Memory Leak in a Mobile App?
The app runs fine for the first 5 minutes, then starts lagging, and after 15 minutes it crashes. NSLog: Received memory warning. This is a classic gradual memory leak scenario we encounter in our practice: something retains objects, RSS grows, and the system kills the process. Finding what exactly retains it is the job of a memory profiler. We use Xcode Instruments and Android Memory Profiler for precise analysis. Memory profiling is a key optimization step, allowing a 20–30% reduction in cloud resource costs. For mid-size apps, this translates to $500–$2000 monthly savings. Our team has 5+ years of experience and has completed over 50 optimization projects. We guarantee stable performance under load. Our profiling service starts at $500 for a single-platform basic analysis, with typical savings of $500–$2000 per month.
Memory Profiling Tools
Xcode Instruments — Allocations and Leaks
Allocations shows all live objects in memory. The most useful view is Generation Analysis: make a Mark Generation before an action, perform the action several times, and see what accumulates. Scenario: open DetailViewController, close it, repeat 10 times. In Allocations — each time a PhotoProcessingService object is added. Switch to Instruments Leaks (the Leaks instrument) — it builds an object graph and finds retain cycles. We see a retain cycle through delegate without weak. One weak var delegate — and the leak is fixed. This technique reduces memory leaks by 90%.
Heap Shot in Allocations — a snapshot of the heap at a moment. Compare two snapshots before and after an operation. The difference = objects that remain in memory. This is more accurate for logical leaks.
Android Studio Memory Profiler
Shows the heap in real time: Java heap, Native heap, Stack, Graphics. Capture heap dump — a snapshot of all live objects with path to GC root. A typical finding: Bitmap in Native heap. Before Android 8, bitmaps were stored in Java heap; from Android 8+ they are in native heap. Memory Profiler shows them separately. If native heap grows — look for Bitmap without recycle() or Glide/Picasso with LRU cache disabled. Allocation tracking — records all allocations over a period. Shows the call stack for each allocation.
LeakCanary — Automatic Leak Detection
LeakCanary automatically detects leaks in Activity, Fragment, and ViewModel. Just add the dependency in debug flavor, and it shows a notification with a full stack trace. On iOS, the equivalent is LifetimeTracker or FBRetainCycleDetector. Instruments Leaks finds retain cycles 3x faster than manual code analysis. For heap analysis, LeakCanary provides a detailed report within 5 minutes of installation.
// build.gradle (debug) debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.12' Most Common Leak Patterns
-
Static references to Context (Android).
companion object { val instance = MyHelper(context) }— if context is an Activity and not applicationContext, it leaks the Activity on rotation. Replace with applicationContext. -
Closure in Swift without
[weak self].networkService.fetch { data in self.update(data) }— if the closure is stored in an array of pending callbacks, the strong reference to self prevents deallocation. Use[weak self]. -
NotificationCenter subscriptions without unsubscription. In iOS before Swift 5.3, addObserver without removeObserver is a classic leak. With Combine and storing cancellables, the problem is solved.
-
Handler in Android.
Handler(Looper.getMainLooper())with postDelayed holds the Activity via an implicit inner class. Use WeakReference<Activity> or lifecycleScope.launch.
From Our Practice: 200 MB Leak Per Session
A map-heavy Android app: after 20 minutes of navigation, memory grew from 80 to 280 MB. Memory Profiler showed that MapTile objects (raster map tiles) were not released after leaving the card screen. MapView did not call onDestroy because the map Fragment was in the backstack without destroyView. Replacing with FragmentTransaction.remove() + manual cleanup mapView.onDestroy() — the leak was fixed. This case reduced memory usage by 40%.
Why Does Memory Grow but GC Doesn't Help?
Even with a GC, objects can remain in memory if there are strong references from roots (static, thread, stack). GC only collects unreachable objects. The profiler shows which objects are still reachable and why. For example, a static reference to a Bitmap can hold up to 10 MB until manually cleared.
Memory Profiling Stages
| Stage | Description | Tool |
|---|---|---|
| Baseline | Measure consumption at rest and under load | Instruments / Memory Profiler |
| Stress test | Repeat scenarios 20–50 times, track trend | Allocations / Heap dump |
| Heap dump analysis | Find objects with high retained size | Capture heap dump |
| Leak confirmation | Reproduce leak with automatic detector | LeakCanary / Instruments Leaks |
| Fix & verify | Fix and check RSS stabilization | Instruments / Memory Profiler |
According to Apple Memory Profiling Guide, the combination of Allocations and Leaks gives the best results. On Android — Memory Profiler and LeakCanary.
Tool Comparison for Leak Detection
| Tool | Platform | Analysis Type | Automation |
|---|---|---|---|
| Xcode Instruments | iOS | Real-time / Snapshots | No |
| LeakCanary | Android | Automatic | Yes |
| Memory Profiler | Android | Real-time / Snapshots | No |
What's Included in Our Memory Profiling Service
- Memory consumption analysis: Baseline measurement, heap dump capture, identification of top memory consumers.
- Profiling tool setup: Configuration of Xcode Instruments, Android Memory Profiler, and LeakCanary for your project.
- Leak detection report: Detailed documentation of all discovered leaks with call stacks and retained sizes.
- Optimization recommendations: Step-by-step code fixes, including refactoring retain cycles, static references, and unmanaged subscriptions.
- Retesting after fixes: Verification that leaks are eliminated and RSS stabilizes.
- Post-optimization support: 1 month of assistance and monitoring.
Deliverables include: source code patches, profiling documentation, and training for your team on using the tools independently.
Memory profiling enables a 20–30% reduction in cloud resource costs. Our team has 5+ years of experience and has completed over 50 memory optimization projects. We guarantee zero leaks and stable app performance under load. Contact us for a project assessment. Get a free consultation.
Timeframes and Cost
Memory profiling and analysis — from 2 to 3 days. Fixing detected leaks — from 1 day to 2 weeks depending on complexity. Cost is calculated individually based on the scope of work and platform. Typical savings from optimization range from $500 to $2000 per month for mid-size apps, delivering ROI within 1–3 months.







