Files
Kordant/tasks/ios-production/10-memory-leak-audit.md
2026-05-26 16:06:34 -04:00

2.6 KiB

10. Memory Management & Leak Audit

meta: id: ios-production-10 feature: ios-production priority: P2 depends_on: [] tags: [performance, memory, production]

objective:

  • Audit and fix memory leaks and retain cycles to ensure stable app performance over long sessions

deliverables:

  • Memory leak audit report
  • Fixed retain cycles in ViewModels and Services
  • Instruments leak check passing
  • Memory usage optimization

steps:

  1. Audit ViewModels for retain cycles:
    • Review all ViewModels in iOS/Kordant/ViewModels/
    • Check for strong references in closures
    • Verify cancellables properly stored and cleaned up
    • Check for delegate patterns causing cycles
  2. Audit Services for leaks:
    • Review APIClient, AuthService, CacheManager
    • Check singleton patterns don't retain view controllers
    • Verify notification observers removed on deinit
    • Check timer/interval cleanup
  3. Run Instruments leak check:
    • Profile app with Leaks instrument
    • Perform all critical user journeys
    • Record and categorize all leaks
    • Fix leaks in priority order (critical first)
  4. Optimize memory usage:
    • Reduce image cache size if needed
    • Limit number of cached API responses
    • Clear unused ViewModels from navigation stack
    • Optimize large data structures
  5. Add memory warnings handling:
    • Clear caches on UIApplication.didReceiveMemoryWarningNotification
    • Reduce quality of background operations
    • Cancel non-essential network requests
  6. Test long-running sessions:
    • Leave app running for 24 hours
    • Monitor memory growth
    • Verify no crashes from memory pressure

tests:

  • Instruments: Leaks instrument shows 0 leaks
  • Performance: Memory stable after 1 hour of use
  • Stress: No crashes after extended usage

acceptance_criteria:

  • 0 memory leaks detected in Instruments
  • No retain cycles in ViewModels or Services
  • Memory usage stable over 1 hour session
  • Memory warnings handled appropriately
  • Caches cleared on low memory
  • No strong reference cycles in closures
  • Notification observers removed on deinit
  • Long-running session (24h) without memory-related crashes

validation:

  • Profile with Instruments → 0 leaks after full app navigation
  • Monitor memory in Xcode → flat line during idle
  • Trigger memory warning → caches cleared, app responsive
  • Extended use test → no memory growth over time

notes:

  • SwiftUI @StateObject and @ObservedObject can cause leaks if misused
  • Use [weak self] in all async closures
  • Combine subscribers must be stored in Set
  • Test on physical device — simulator behaves differently