內(nèi)存布局

- 棧(stack):方法調(diào)用,局部變量,是連續(xù)的,高地址向低地址擴(kuò)展
- 堆(heap):通過(guò)alloc等分配的對(duì)象,是離散的,低地址向高地址擴(kuò)展,需要手動(dòng)管理
- 未初始化數(shù)據(jù)(bss):未初始化的全局變量等
- 已初始化數(shù)據(jù)(data):已初始化的全局變量等
- 代碼段(text):程序代碼
問(wèn)題一 :Autoreleasepool是實(shí)現(xiàn)機(jī)制是什么?它是什么時(shí)候釋放內(nèi)部的對(duì)象的?它內(nèi)部的數(shù)據(jù)結(jié)構(gòu)是什么樣的?當(dāng)我提到哨兵對(duì)象時(shí),會(huì)繼續(xù)問(wèn)哨兵對(duì)象的作用是什么,為什么要設(shè)計(jì)它?
編譯器會(huì)將 @autoreleasepool {} 改寫(xiě)為:
void * ctx = objc_autoreleasePoolPush;
{}
objc_autoreleasePoolPop(ctx);
- objc_autoreleasePoolPush:
把當(dāng)前next位置置為nil,即哨兵對(duì)象,然后next指針指向下一個(gè)可入棧位置,AutoreleasePool的多層嵌套,即每次objc_autoreleasePoolPush,實(shí)際上是不斷地向棧中插入哨兵對(duì)象。 - objc_autoreleasePoolPop:
根據(jù)傳入的哨兵對(duì)象找到對(duì)應(yīng)位置。
給上次push操作之后添加的對(duì)象依次發(fā)送release消息。回退next指針到正確的位置。
Autoreleasepool的原理是一個(gè)雙向列表,它會(huì)對(duì)加入其中的對(duì)象實(shí)現(xiàn)延遲釋放。
當(dāng)Autoreleasepool調(diào)用drain方法時(shí)會(huì)釋放內(nèi)部標(biāo)記為autorelease的對(duì)象
Autoreleasepool數(shù)據(jù)結(jié)構(gòu)
class AutoreleasePoolPage {
magic_t const magic;
id *next;
pthread_t const thread;
AutoreleasePoolPage * const parent;
AutoreleasePoolPage *child;
uint32_t const depth;
uint32_t hiwat;
};
哨兵對(duì)象類(lèi)似一個(gè)指針,指向自動(dòng)釋放池的棧頂位置,它的作用就是用于標(biāo)記當(dāng)前自動(dòng)釋放池需要釋放內(nèi)部對(duì)象時(shí),釋放到那個(gè)地方結(jié)束,每次入棧時(shí)它用于確定添加的位置,然后再次移動(dòng)到棧頂。
Autoreleasepool詳細(xì)內(nèi)容 容易理解
問(wèn)題二 :哪些對(duì)象會(huì)放入到Autoreleasepool中?
有兩種情況生成的對(duì)象會(huì)加入到autoreleasepool中:
- 非alloc/new/copy/mutablecopy 開(kāi)始的方式初始化時(shí)
- id的指針或?qū)ο蟮闹羔樤跊](méi)有顯示指定時(shí)