引文:
-
內(nèi)存布局
-
內(nèi)存管理方案
-
數(shù)據(jù)結(jié)構(gòu)
-
ARC&MRC
-
引用計(jì)數(shù)
-
弱引用
-
自動(dòng)釋放池
-
循環(huán)引用

內(nèi)存布局 (從低到高分配)
棧(stack): 方法調(diào)用
堆(heap): 通過(guò)alloc分配的對(duì)象
bss: 未初始化的全局變量等
data: 已初始化的全局變量等
text: 程序的代碼段
內(nèi)存管理方案
TaggedPointer: 程序?qū)π?shù)據(jù)量?jī)?yōu)化(防止crash等)
NONPOINTER_ISA
散列表
怎樣實(shí)現(xiàn)快速分流?

數(shù)據(jù)結(jié)構(gòu)
Spinlock_t (自旋鎖)
Spinlock_t 是一種"盲等"的鎖,(一直循環(huán)去詢(xún)問(wèn)訪問(wèn))
適應(yīng)于輕量的訪問(wèn)
RefcountMap (引用計(jì)數(shù)表)

weak_table_t (弱引用表)
使用對(duì)象指針作為key,通過(guò)hash函數(shù)找到到對(duì)應(yīng)的value

ARC (自動(dòng)引用計(jì)數(shù))
ARC是
LLVM和Runtime協(xié)作的結(jié)果ARC中禁止手動(dòng)調(diào)用
retain/release/retainCount/dealloc方法ARC中新增
strong和weak屬性關(guān)鍵字
引用計(jì)數(shù)管理
alloc的實(shí)現(xiàn)
經(jīng)過(guò)調(diào)用鏈最終會(huì)調(diào)用c函數(shù)
calloc方法, 并且引用計(jì)數(shù)不會(huì)+1
retain實(shí)現(xiàn)
SideTable &table = SideTables()[this];
size_t &refcntStorage = table.refcnts[this];
refcntStorage += SIDE_TABLE_RC_ONE;
retainCount實(shí)現(xiàn)
SideTable &table = SideTables()[this];
size_t refcnt_result = 1;
RefcountMap::iterator it = table.refcnts.find(this);
refcnt_result += it->second >> SIDE_TABLE_RC_SHIFT

object_dispose()實(shí)現(xiàn)

自動(dòng)釋放池
是以棧為方式的通過(guò)雙向鏈表的形式組合而成的
是和線程一一對(duì)應(yīng)的
編譯器會(huì)將@autoreleasepool{} 改寫(xiě)為:
void *ctx = objc_autoreleasePoolPush();
// 業(yè)務(wù)邏輯
autoreleasePoolPop(ctx)
AutoreleasePoolPage

AutoreleasePoolPage::pop
根據(jù)傳入的對(duì)象找到入棧的對(duì)應(yīng)位置.
給上次push操作之后添加的對(duì)象依次執(zhí)行release消息
回退next指針到正確的位置
在每次runloop將要結(jié)束的時(shí)候調(diào)用AutoreleasePoolPage::pop()
多層嵌套就是多次插入哨兵對(duì)象
在for循環(huán)中alloc圖片數(shù)據(jù)等占用內(nèi)存比較大的場(chǎng)景中手動(dòng)調(diào)用autoreleasePool
循環(huán)引用
類(lèi)型:
- 自循環(huán)引用
- 相互循環(huán)引用
- 多循環(huán)引用
一般代理/bolck/NSTimer/大環(huán)引用 都有可能引起循環(huán)引用, 所有開(kāi)發(fā)者應(yīng)該盡量避免循環(huán)引用,
如果已經(jīng)產(chǎn)生了循環(huán)引用,則需要在合適的時(shí)機(jī)手動(dòng)斷環(huán)
解決方案:
__weak
一般采取這種方式解決循環(huán)引用(修飾對(duì)象)
OC的特點(diǎn)會(huì)對(duì)weak修飾的對(duì)象在釋放的時(shí)候自動(dòng)置為nil
__block
MRC:__block修飾的對(duì)象不會(huì)增加引用計(jì)數(shù),避免了循環(huán)引用
ARC:__block修飾的對(duì)象會(huì)產(chǎn)生強(qiáng)引用,無(wú)法避免循環(huán)引用.需要手動(dòng)解除
__unsafe_unretained
修飾的對(duì)象不會(huì)產(chǎn)生循環(huán)引用,但是如果對(duì)象在某一時(shí)刻被釋放了會(huì)產(chǎn)生懸垂指針
關(guān)于NSTimer 產(chǎn)生的循環(huán)引用我們可以采用中間對(duì)象的形式來(lái)解決