Beginner's Guide to iOS Memory Analysis: Virtual Memory, Heap, Autoreleasepool, and Leaks
This beginner‑level guide explains iOS virtual‑memory and heap fundamentals, demonstrates how autorelease‑pool buildup and retain‑cycle leaks cause out‑of‑memory crashes, and shows step‑by‑step use of Xcode’s Memory Graph, Instruments Allocations, and leak detection tools, plus tips on weak versus unowned references.
Abstract: This beginner‑level article introduces iOS memory analysis techniques, focusing on virtual memory, heap memory, AutoreleasePool accumulation, and leaks detection. It demonstrates how to use Xcode’s Memory Graph and Instruments (Allocations) to identify and resolve common memory problems.
Introduction
Out‑of‑memory (OOM) issues are frequent in iOS development and are not trivial to solve. The article first explains two typical memory‑abnormal patterns and then shows how to use the official tools Memory Graph and Instruments to analyze and optimise memory usage.
Basic Knowledge
Understanding Virtual Memory
iOS apps run in a virtual memory space. The total virtual memory consumption can be approximated as number_of_pages * page_size (16 KB) . The “footprint” reported by Xcode or Jetsam is calculated from the number of dirty and compressed pages, not from the raw virtual address space.
Key concepts:
Virtual memory usage = total pages × page size (16 KB).
Conventional memory usage = (dirty + compressed) pages × page size.
The article also lists example memory limits for iPhone 13 Pro and shows how Apple’s virtual‑memory‑extension entitlements can increase the usable limits.
What Is Heap Memory?
When developers allocate memory with malloc , alloc , new , or mmap , the memory belongs to different REGION TYPEs. Heap allocations appear as Malloc xxxx regions, while mmap and VM_ALLOCATION are considered mapped files and are not part of the heap.
Analysis Tools Overview
Xcode Memory Report
The Memory Report shows the overall memory trend but cannot pinpoint the cause of a spike.
Memory Graph
Memory Graph captures a snapshot of the app’s memory graph, allowing developers to inspect object reference relationships. Enabling MallocStackLogging in the scheme diagnostics shows the allocation stack for each node. Selecting “Live Allocations Only” reduces noise.
Instruments – Allocations
Allocations sorts heap objects by type or by allocation stack, making it easy to locate the largest memory consumers. Exported .graph files can be opened in Instruments for deeper analysis.
Classic Problem Cases
AutoreleasePool Accumulation
A demo creates one million NSString objects inside a button‑triggered loop. Without an inner AutoreleasePool, the app exhibits sharp memory spikes.
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(0,0,400,400)];
[btn setTitle:@"触发Autoreleasepool对象堆积" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(doSomeThings) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
- (void)doSomeThings {
for (int i = 0; i < 1000000; i++) {
NSString *tempString = [NSString stringWithFormat:@"Temporary String %d", i];
}
}Allocations shows that CFString objects dominate the memory usage (≈45 MiB, 993 992 objects). Adding an inner AutoreleasePool eliminates the spike:
for (int i = 0; i < 1000000; i++) {
@autoreleasepool {
NSString *tempString = [NSString stringWithFormat:@"Temporary String %d", i];
}
}Leaks (Memory Leaks)
Leaks are memory blocks that are allocated but no longer reachable. The article demonstrates a typical retain‑cycle involving ThumbnailRenderer , cacheProvider , ThreadnailLoader , and a Swift closure. Breaking the cycle with a weak reference resolves the leak:
loader.completionHandler = { [weak renderer] in
guard let renderer = renderer else { return }
self.thumbnails = renderer.images
}Leaks Detection Principle
The leaks tool scans the process’s global memory (e.g., __DATA, registers, stack) and marks any malloc‑allocated block that is not referenced anywhere as a leak. False negatives can occur if a random value coincidentally matches a malloc address.
Performance Difference Between weak and unowned
weak references are safe but incur extra memory and slower access. unowned references are faster and have no extra storage, but accessing a deallocated object crashes. Use unowned only when the referenced object’s lifetime is guaranteed to outlive the holder.
Extended Knowledge
For further memory‑monitoring, the article recommends open‑source tools such as MLeaksFinder for runtime leak detection and Matrix’s WCMemoryStatPlugin for production‑side allocation logs.
Conclusion
The article walks from virtual‑memory fundamentals to practical usage of Xcode’s Memory Graph, Instruments Allocations, and Leaks detection, covering two classic issues (AutoreleasePool accumulation and leaks) and discussing weak vs. unowned references.
Sohu Tech Products
A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.