# Xcode Memory Graph Shows Leaks in Kotlin Multiplatform + SwiftUI App
## Summary
- Xcode Memory Graph reported immediate leaks (`__NSArrayI`, `__NSCFString`, `MTLAttributeInternal`) in a brand-new Kotlin Multiplatform (KMP) + SwiftUI app
- Leaks occur in the default Compose Multiplatform template without custom code
- Memory usage stabilizes over time with no actual growth observed
- Confirmed as false positives in Xcode's instrumentation cache detection
## Root Cause
- Apple's system caches (Metal/Foundation internals) not fully tracked by Xcode Memory Graph:
- `MTLAttributeInternal`: Metal API shader attribute cache initialization
- `__NSArrayI`/`__NSCFString`: Foundation framework immutable collection allocations
- SwiftUI + KMP bridging layers trigger initialization of system caches early
- Static KMP framework links to unmanaged CoreFoundation resources
## Why This Happens in Real Systems
- Hybrid SwiftUI/KMP setups activate multiple subsystem caches simultaneously
- Metal API (required by Compose rendering) allocates GPU-related resources
- Xcode interprets unreleased caches as leaks because:
- Memory Graph doesn't flag system caches as explicitly "safe"
- Kotlin/Native memory management isn't fully visible to ARC
- Initial cache allocations appear long-lived but remain bounded
## Real-World Impact
- False positives wasting developer debugging time
- Difficulty onboarding new team members to KMP projects
- Erosion of trust in Xcode diagnostics
- No actual effect on runtime stability or memory growth
- Potential masking of real leaks later in development
## Example or Code
Initialization flow triggering Metal cache:
```swift
// ComposeView.swift
struct ComposeView: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> UIViewController {
// Triggers Metal subsystem initialization
MainViewControllerKt.MainViewController()
}
}
Xcode-reported leaks:

How Senior Engineers Fix It
- Verify leak persistence across multiple relaunches
- Correlate with Instruments allocations:
instruments -t "Allocations" -leaks app_bundle.app - Check for growth patterns with heap snapshots
- Isolate Compose in test view:
Text("TEST VIEW").onAppear { // Check Leaks without ComposeView } - Conditionally disable Metal in Compose:
// MainViewController.kt fun MainViewController(): UIViewController = ComposeUIViewController { App(useSoftwareRendering = true) } - Suppress false positives via diagnostic ignores
Why Juniors Miss It
- Over-reliance on Xcode diagnostics as ground truth
- Misinterpreting clustered system allocations as leaks
- Lack of Metal API lifecycle awareness
- Not validating memory growth patterns over time
- Not isolating framework initialization effects
- Hesitation to dismiss profiling tool warnings