iOS自動釋放池

原作者原文鏈接:http://blog.sunnyxx.com/2014/10/15/behind-autorelease/

Autorelease對象什么時候被釋放

在沒有手加Autorelease Pool的情況下,Autorelease對象是在當(dāng)前的runloop迭代結(jié)束時釋放的镊屎,而他能夠釋放的原因是 系統(tǒng)在每個runloop的迭代中都加入了自動釋放池的push和pop获黔。

AutoreleasePoolPage

ARC下绢记,我們使用@autoreleasepool{}來使用一個AutoreleasePool站玄,隨后編譯器將其改寫成下面的樣子:

void *context = objc_autoreleasePoolPush();

// {}中的代碼

objc_autoreleasePoolPop(context);

而這兩個函數(shù)都是對AutoreleasePoolPage的簡單封裝谆沃,所以自動釋放機(jī)制的核心就在于這個類游盲。

AutoreleasePoolPage是一個C++實(shí)現(xiàn)的類
Autorelease對象什么時候被釋放

在沒有手加Autorelease Pool的情況下,Autorelease對象是在當(dāng)前的runloop迭代結(jié)束時釋放的痹兜,而他能夠釋放的原因是 系統(tǒng)在每個runloop的迭代中都加入了自動釋放池的push和pop穆咐。

AutoreleasePoolPage

ARC下,我們使用@autoreleasepool{}來使用一個AutoreleasePool字旭,隨后編譯器將其改寫成下面的樣子:

void *context = objc_autoreleasePoolPush();

// {}中的代碼

objc_autoreleasePoolPop(context);

而這兩個函數(shù)都是對AutoreleasePoolPage的簡單封裝庸娱,所以自動釋放機(jī)制的核心就在于這個類。

AutoreleasePoolPage是一個C++實(shí)現(xiàn)的類

image.png
  • AutoreleasePool并沒有單獨(dú)的結(jié)構(gòu)谐算,而是由若干個AutoreleasePoolPage以雙向鏈表的形式組合而成(分別對應(yīng)結(jié)構(gòu)中的parent指針和child指針)
  • AutoreleasePool是按線程一一對應(yīng)的(結(jié)構(gòu)中的thread指針指向當(dāng)前線程)
  • AutoreleasePoolPage每個對象會開辟4096字節(jié)內(nèi)存(也就是虛擬內(nèi)存一頁的大小)归露,除了上面的實(shí)例變量所占空間洲脂,剩下的空間全部用來儲存autorelease對象的地址
  • 上面的id *next指針作為游標(biāo)指向棧頂最新add進(jìn)來的autorelease對象的下一個位置
  • 一個AutoreleasePoolPage的空間被占滿時,會新建一個AutoreleasePoolPage對象剧包,連接鏈表恐锦,后來的autorelease對象在新的page加入

所以,若當(dāng)前線程中只有一個AutoreleasePoolPage對象疆液,并記錄了很多autorelease對象地址時內(nèi)存如下圖:


image2.png

圖中的情況一铅,這一頁再加入一個autorelease對象就要滿了(也就是next指針馬上指向棧頂),這時就要執(zhí)行上面說的操作堕油,建立下一頁page對象潘飘,與這一頁鏈表連接完成后肮之,新page的next指針被初始化在棧底(begin的位置),然后繼續(xù)向棧頂添加新對象卜录。

所以戈擒,向一個對象發(fā)送- autorelease消息,就是將這個對象加入到當(dāng)前AutoreleasePoolPage的棧頂next指針指向的位置

釋放時刻

每當(dāng)進(jìn)行一次objc_autoreleasePoolPush調(diào)用時艰毒,runtime向當(dāng)前的AutoreleasePoolPage中add進(jìn)一個哨兵對象筐高,值為0(也就是個nil),那么這一個page就變成了下面的樣子:

image3.png

objc_autoreleasePoolPush的返回值正是這個哨兵對象的地址丑瞧,被objc_autoreleasePoolPop(哨兵對象)作為入?yún)⒏掏粒谑牵?/p>

  1. 根據(jù)傳入的哨兵對象地址找到哨兵對象所處的page
  2. 在當(dāng)前page中,將晚于哨兵對象插入的所有autorelease對象都發(fā)送一次- release消息绊汹,并向回移動next指針到正確位置
  3. 補(bǔ)充2:從最新加入的對象一直向前清理稽屏,可以向前跨越若干個page,直到哨兵所在的page

剛才的objc_autoreleasePoolPop執(zhí)行后灸促,最終變成了下面的樣子:


image4.png

嵌套的AutoreleasePool

知道了上面的原理诫欠,嵌套的AutoreleasePool就非常簡單了,pop的時候總會釋放到上次push的位置為止浴栽,多層的pool就是多個哨兵對象而已荒叼,就像剝洋蔥一樣,每次一層典鸡,互不影響被廓。

使用容器的block版本的枚舉器時,內(nèi)部會自動添加一個AutoreleasePool:

[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

// 這里被一個局部@autoreleasepool包圍著

}];

當(dāng)然萝玷,在普通for循環(huán)和for in循環(huán)中沒有嫁乘,所以,還是新版的block版本枚舉器更加方便球碉。for循環(huán)中遍歷產(chǎn)生大量autorelease變量時蜓斧,就需要手加局部AutoreleasePool咯。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末睁冬,一起剝皮案震驚了整個濱河市挎春,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌豆拨,老刑警劉巖直奋,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異施禾,居然都是意外死亡脚线,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進(jìn)店門弥搞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來邮绿,“玉大人渠旁,你說我怎么就攤上這事∷孤担” “怎么了一死?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長傻唾。 經(jīng)常有香客問我投慈,道長,這世上最難降的妖魔是什么冠骄? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任伪煤,我火速辦了婚禮,結(jié)果婚禮上凛辣,老公的妹妹穿的比我還像新娘抱既。我一直安慰自己,他們只是感情好扁誓,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布防泵。 她就那樣靜靜地躺著,像睡著了一般蝗敢。 火紅的嫁衣襯著肌膚如雪捷泞。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天寿谴,我揣著相機(jī)與錄音锁右,去河邊找鬼。 笑死讶泰,一個胖子當(dāng)著我的面吹牛咏瑟,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播痪署,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼码泞,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了狼犯?” 一聲冷哼從身側(cè)響起余寥,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎辜王,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體罐孝,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡呐馆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了莲兢。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片汹来。...
    茶點(diǎn)故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡续膳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出收班,到底是詐尸還是另有隱情坟岔,我是刑警寧澤,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布摔桦,位于F島的核電站社付,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏邻耕。R本人自食惡果不足惜鸥咖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望兄世。 院中可真熱鬧啼辣,春花似錦、人聲如沸御滩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽削解。三九已至富弦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間钠绍,已是汗流浹背舆声。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留柳爽,地道東北人媳握。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像磷脯,于是被迫代替她去往敵國和親蛾找。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內(nèi)容