在 iOS 應用開發中,內存管理一直是確保應用性能和效率的重要方面。自動參考計數(Automatic Reference Counting, ARC)大大簡化了內存管理的過程。本文在深入解析 ARC 的運作機制,比較它與 MRC 的區別,並探討 iOS 在不同情境下的內存管理策略。
ARC 簡介:自動化的內存管理
ARC,或稱自動參考計數,是 LLVM 編譯器和 Runtime 系統合作的結果,自動管理 reference type 的 instance object 被引用的次數。與手動參考計數(Manual Reference Counting, MRC)相比,開發者不再需要手動插入 retain
和 release
代碼,大幅降低了內存泄露和其他內存問題的風險。
ARC 的工作原理:
- Value Type vs. Reference Type:ARC 僅管理 reference type 的 instances,如 class 的實例,而非 value type(如 struct 和 enum)。
- Retain Counts 的管理:
- Strong Reference:當你聲明一個 class instance 為 strong reference 時,ARC 會自動將其 retain count +1。
- Weak 和 Unowned Reference:與 strong reference 相對,這兩種參考不會增加 instance 的 retain count,幫助解決循環引用的問題。
從 MRC 到 ARC:內存管理的進化
在 ARC 之前,iOS 開發者必須手動管理內存,這要求他們精確地控制每個 object 的生命週期。這不僅耗時且易出錯,還增加了開發的複雜度。ARC 的引入,讓 LLVM 在編譯時自動插入內存管理代碼,從根本上解決了這一挑戰。
ARC 與垃圾回收:兩種內存管理策略的比較
不同於 Java 或 C# 中的垃圾回收(Garbage Collection, GC),GC 在運行時動態管理內存,可能會導致性能不穩定。相反,ARC 在編譯時期就處理好了內存管理問題,提供了更加穩定和預測的性能表現。
iOS 的進階內存管理技術
雖然 ARC 大大簡化了內存管理,但 iOS 開發還包括其他進階技術,如
- TaggedPointer: 對小的 instance object 如 NSNumber 就使用 TaggedPointer 來記錄
- NONPOINTER_ISA: isa pointer 在 64 bit 的架構下,雖然會在 memory 中佔 64 bits,但實際上只需 40 bits 就可以儲存所有的資訊,因此 iOS 為了節省空間,剩餘 24 bits 可用來儲存內存管理所需的相關數據
- Side Tables: 以 instance object 的 pointer 為 index 的 hash table,value 為 retain count table(RefcountMap) 以及 weak referenced table(weak_table_t)
iOS 可用 O(1) 的時間找到其 instance object 所對應的 retain count table 以及 weak referenced table
且使用 spin lock 確保再多線程的環境下,可以 thread safe 地讀寫 side table(每 8 個 tables 配一個 spin lock,確保系統可以同時訪問多組 tables)