iOS的自動釋放池(AutoReleasePool)

viewDidLoad中通過NSMutebleArray的array類方法創(chuàng)建數(shù)組對象惧辈,這個array對象的內(nèi)存是在什么時機(jī)釋放的?
在每一次runloop循環(huán)將要結(jié)束時,會對前一次創(chuàng)建的AutoreleasePool進(jìn)行pop操作,同時會push進(jìn)來一個新的AutoreleasePool,所以在viewDidLoad中所創(chuàng)建的array對象,是在當(dāng)次runloop將要結(jié)束的時候,調(diào)用AutoreleasePoolPage的pop方法中釋放的。

AutoreleasePool的實現(xiàn)原理是怎樣的?

@autoreleasepool{}在編譯器的內(nèi)部實現(xiàn)如下:

//在autoreleasepool中的所有對象,都會添加到自動釋放池中,當(dāng)進(jìn)行pop之后, autoreleasepool中所有對象都會被發(fā)送一次release消息
@ autoreleasepool {
  //AutoreleasePoolPage是C++類,調(diào)用它里面的push方法
    void *ctx = objc_autoreleasePoolPush(){
        void *objc_autoreleasePoolPush(void)
                                |
        void *AutoreleasePoolPage::push(void)
     };
 
//調(diào)用AutoreleasePoolPage中的pop函數(shù),一次pop實際上相當(dāng)于一次批量的pop操作
    objc_autoreleasePoolPop(ctx){
        void objc_autoreleasePoolPop(void *ctxt)
                                  |
        AutoreleasePoolPage::pop(void *ctxt)
    };
}

AutoreleasePool為何可以嵌套使用?

自動釋放池的數(shù)據(jù)結(jié)構(gòu)
1.是以棧為結(jié)點(diǎn)通過雙向鏈表的形式組合而成
2.是和線程一一對應(yīng)的

雙向鏈表

黑色箭頭代表父指針
紅色箭頭代表Child指針
Node是一個頭結(jié)點(diǎn),它的父指針指向空,后續(xù)會有各個結(jié)點(diǎn),后續(xù)每個結(jié)點(diǎn)都有兩個指針,父指針指向前一個結(jié)點(diǎn),Child指針指向后一個結(jié)點(diǎn),最后一個指針的Child指針指向一個空結(jié)點(diǎn)磕瓷。

棧是向下增長的,所以下面是高地址,上面是低地址,對棧的操作實際是有入棧和出棧兩種操作盒齿。
棧的特點(diǎn)是后入先出,后加入棧的對象會最先出棧困食。

AutoreleasePoolPage

這個類的主要有四個成員變量
next: 指向棧中下一個可填充的位置边翁。
parent: 雙向鏈表中的父指針。
child: 雙向鏈表中的child指針硕盹。
thread: 說明AutoreleasePool是和線程一一對應(yīng)的符匾。

下圖是AutoreleasePoolPage的一個結(jié)構(gòu)
最下面是自身占用內(nèi)存,上面是用來存儲AutoreleasePool中填充的對象,next指針指向當(dāng)前棧的空位置,若此時進(jìn)行入棧操作,就可以添加到next指針?biāo)赶虻奈恢?/p>

AutoreleasePoolPage中Push方法的內(nèi)部實現(xiàn)

假如next在上圖位置,此時我們push操作,會把當(dāng)前next的位置置為nil,也叫做哨兵對象,然后將next指針指向下一個可入棧的位置。
實際上每次進(jìn)行AutoreleasePool的代碼塊創(chuàng)建的時候,相當(dāng)于不斷的在棧中去插入哨兵對象瘩例。

[obj autorelease]方法實現(xiàn)

當(dāng)我們調(diào)用了一個對象的autorelease,首先會判斷當(dāng)前next指針是否指向棧頂,若沒有指向棧頂,則直接把對象添加到當(dāng)前棧的next位置啊胶。
假如當(dāng)前next已經(jīng)位于棧頂,那么當(dāng)前AutoreleasePoolPage就沒辦法添加新的autorelease對象了,于是需要增加一個棧結(jié)點(diǎn)拼接到鏈表上,之后再新的棧上面添加對象。

下面看運(yùn)行過程

若此時next指針指向某個位置,若我們添加了新的對象obj(3)(調(diào)用obj(3)的autorelease),放到next位置之后,next指針就會移動到新的位置,再添加新的對象到next位置,next指針繼續(xù)移動到新的位置....

AutoreleasePoolPage中Pop方法的內(nèi)部實現(xiàn)

1.根據(jù)傳入的哨兵對象來找到pop的對應(yīng)位置仰剿。
2.給上次push操作之后添加的對象依次發(fā)送release消息创淡。

  • 回退next指針到正確位置。
  • 根據(jù)上面的圖,假如此時next指針指向obj(n)的上方,若此時調(diào)用了autoreleasePop操作,是要給紅括號包含的所有對象依次發(fā)送realease消息,假如發(fā)送完,這些對象就會從當(dāng)前棧中清除,清除之后會把next指針指向正確的位置南吮。

總結(jié)

自動釋放池

1.在當(dāng)次runloop將要結(jié)束的時候調(diào)用AutoreleasePoolPage::pop()琳彩。
2.autoreleasePool的多層嵌套調(diào)用就是多次插入哨兵對象,當(dāng)我們每次進(jìn)行autoreleasePool代碼塊創(chuàng)建的時候,系統(tǒng)就會為我們進(jìn)行哨兵對象的插入。
3.autoreleasePool的使用場景: 在for循環(huán)中alloc出大量的圖片數(shù)據(jù)等內(nèi)存消耗較大,需要在for循環(huán)內(nèi)部手動插入autoreleasePool,每一次for循環(huán),都進(jìn)行一次內(nèi)存的釋放,來降低內(nèi)存的峰值部凑。

AutoreleasePool的實現(xiàn)原理

以棧為結(jié)點(diǎn),通過雙向鏈表形式組合而成的一個數(shù)據(jù)結(jié)構(gòu)露乏。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市涂邀,隨后出現(xiàn)的幾起案子瘟仿,更是在濱河造成了極大的恐慌,老刑警劉巖比勉,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件劳较,死亡現(xiàn)場離奇詭異,居然都是意外死亡浩聋,警方通過查閱死者的電腦和手機(jī)观蜗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來衣洁,“玉大人墓捻,你說我怎么就攤上這事》环颍” “怎么了砖第?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵撤卢,是天一觀的道長。 經(jīng)常有香客問我梧兼,道長放吩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任羽杰,我火速辦了婚禮屎慢,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘忽洛。我一直安慰自己腻惠,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布欲虚。 她就那樣靜靜地躺著集灌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪复哆。 梳的紋絲不亂的頭發(fā)上欣喧,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機(jī)與錄音梯找,去河邊找鬼唆阿。 笑死,一個胖子當(dāng)著我的面吹牛锈锤,可吹牛的內(nèi)容都是我干的驯鳖。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼久免,長吁一口氣:“原來是場噩夢啊……” “哼浅辙!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起阎姥,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤记舆,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后呼巴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體泽腮,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年衣赶,在試婚紗的時候發(fā)現(xiàn)自己被綠了诊赊。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡屑埋,死狀恐怖豪筝,靈堂內(nèi)的尸體忽然破棺而出痰滋,到底是詐尸還是另有隱情摘能,我是刑警寧澤续崖,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站团搞,受9級特大地震影響严望,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜逻恐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一像吻、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧复隆,春花似錦拨匆、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至亏栈,卻和暖如春台腥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背绒北。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工黎侈, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人闷游。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓峻汉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親脐往。 傳聞我的和親對象是個殘疾皇子俱济,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評論 2 355

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