關於autoreleasepool記憶體管理
首先要從MRC說起,我們都知道MRC階段,記憶體管理都是有程式猿手動管理的;那麼就必須要說到記憶體管理的黃金法則:
- 自己生成的物件,自己持有(通過alloc/new/copy/mutableCopy)retain **
- 非自己生成的物件,自己也能持有(除了以alloc/new/copy/mutableCopy開頭的方法)
- 不再需要持有自己持有物件時釋放 release
- 無法釋放非自己持有的物件
當然到了ARC時期,編譯器幫我們做了這些事情,當然關於autorelease的事情也是編譯幫我做的。
- autoreleasepool是什麼?
自動釋放池,像資料結構棧一樣的結構,autorelease物件push到自動釋放池,非手動建立的情況下,自動釋放池會在runloop迭代結束的時候對“哨兵物件”之後的autorelease物件進行一次release操作,autorelease也會在runloop迭代結束釋放。手動建立的autoreleasepool會在大括弧結束進行釋放。 - 什麼物件會加入到autoreleasepool?
MRC時期我們可以採用[objc autorelease], 加入到當前的自動釋放池。ARC不在需要,也不允許我們如此加入,編譯器會自動給我加入。那麼什麼物件是autorelease物件?即“黃金法則”第二條,非alloc/new/copy/mutableCopy開頭的構造方法生成的物件都會先加入到autoreleasePool,比如[NSMutableArray array]、[UIImage imageNamed:@"xxx"]、[NSString stringWithFormat:@"test stringq"] - 什麼情況下需要手動建立autoreleasePool
根據官方文件總共有三條情況下我們需要建立autoreleasepool。- 基於命令列的程式
- 建立輔助執行緒
- for 迴圈中建立大量的autorelease物件
- 驗證一下
@implementation ViewController
__weak NSString *__weakString = nil;
__weak UIImage *__weakImage = nil;
- (void)viewDidLoad {
[super viewDidLoad];
// 1.
// NSString *string = [NSString stringWithFormat:@"haoYuhong--------計算機絲是"];
// UIImage *image = [UIImage imageNamed:@"bofang-2"];
// __weakString = string;
// __weakImage = image;
// 2.
@autoreleasepool {
UIImage *image = [UIImage imageNamed:@"bofang-2"];
NSString *string = [NSString stringWithFormat:@"haoYuhong--------計算機絲是"];
// NSString *string = [NSString stringWithFormat:@"haoYuhong"];
__weakImage = image;
__weakString = string;
}
NSLog(@"%@", __weakString);
NSLog(@"%@", __weakImage);
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSLog(@"%@", __weakString);
NSLog(@"%@", __weakImage);
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSLog(@"%@", __weakString);
NSLog(@"%@", __weakImage);
}
第一種情況下,我們會看到
2019-02-18 17:11:09.134399+0800 AutoreleasePool[25252:4061510] haoYuhong--------計算機絲是
2019-02-18 17:11:09.134563+0800 AutoreleasePool[25252:4061510] <UIImage: 0x6040000b1580>, {200, 200}
2019-02-18 17:11:09.134749+0800 AutoreleasePool[25252:4061510] haoYuhong--------計算機絲是
2019-02-18 17:11:09.134897+0800 AutoreleasePool[25252:4061510] <UIImage: 0x6040000b1580>, {200, 200}
2019-02-18 17:11:09.139543+0800 AutoreleasePool[25252:4061510] (null)
2019-02-18 17:11:09.139678+0800 AutoreleasePool[25252:4061510] (null)
第二種情況輸出:
2019-02-18 17:12:24.893067+0800 AutoreleasePool[25284:4063032] (null)
2019-02-18 17:12:24.893245+0800 AutoreleasePool[25284:4063032] (null)
2019-02-18 17:12:24.893472+0800 AutoreleasePool[25284:4063032] (null)
2019-02-18 17:12:24.893592+0800 AutoreleasePool[25284:4063032] (null)
2019-02-18 17:12:24.897735+0800 AutoreleasePool[25284:4063032] (null)
2019-02-18 17:12:24.897892+0800 AutoreleasePool[25284:4063032] (null)
在沒有手動新增autoreleasepool的情況下,編譯自動將新增autorelease物件到主執行緒的自動釋放池,所以物件會延遲釋放。當手動新增autoreleasepool的情況下,作用域結束之後就就會釋放一次,當前pool中的autorelease物件。
注意:為什麼NSString物件長度我要保持在>9呢?<=9會是什麼情況,這裡邊其中有大奧祕,點選這裡看我的另一篇文章。
關於autoreleasePool的原始碼解析,其實千篇一律,道理都是一樣的,許許多多的人都寫過了,也分析了。這裡我將我閱讀的解析原始碼大神的文章附上:
相關文章
- 關於redis記憶體分析,記憶體優化Redis記憶體優化
- 記憶體管理 記憶體管理概述記憶體
- [轉帖]關於記憶體管理:計算頁表大小記憶體
- 記憶體管理篇——實體記憶體的管理記憶體
- 【記憶體管理】記憶體佈局記憶體
- 關於JavaScript的記憶體機制JavaScript記憶體
- 記憶體管理兩部曲之實體記憶體管理記憶體
- Go:記憶體管理與記憶體清理Go記憶體
- Java的記憶體 -JVM 記憶體管理Java記憶體JVM
- iOS 記憶體管理相關面試題iOS記憶體面試題
- 【記憶體管理】Oracle AMM自動記憶體管理詳解記憶體Oracle
- 記憶體管理兩部曲之虛擬記憶體管理記憶體
- 關於 PHP 記憶體溢位的思考PHP記憶體溢位
- 關於持久記憶體(PMem)你知道多少?記憶體
- 關於虛擬機器記憶體和JVM記憶體設定的思考虛擬機記憶體JVM
- Flink記憶體管理記憶體
- 記憶體管理-swMemoryGlobal記憶體
- MySQL記憶體管理MySql記憶體
- JavaScript 記憶體管理JavaScript記憶體
- iOS 記憶體管理iOS記憶體
- Android記憶體管理Android記憶體
- OC記憶體管理記憶體
- 【記憶體管理】Oracle如何使用ASMM自動共享記憶體管理記憶體OracleASM
- linux記憶體管理(一)實體記憶體的組織和記憶體分配Linux記憶體
- [20191220]關於共享記憶體段相關問題.txt記憶體
- 關於PHP記憶體洩漏的問題PHP記憶體
- Linux實體記憶體管理Linux記憶體
- C++記憶體管理C++記憶體
- Windows記憶體管理-分段Windows記憶體
- JavaScript的記憶體管理JavaScript記憶體
- CF的記憶體管理。記憶體
- HotSpot JVM 記憶體管理HotSpotJVM記憶體
- iOS 記憶體管理MRCiOS記憶體
- “理解”iOS記憶體管理iOS記憶體
- iOS 記憶體管理研究iOS記憶體
- 01記憶體管理-概述記憶體
- python的記憶體管理Python記憶體
- 管理 Bitmap 記憶體(譯)記憶體