內(nèi)存管理相關(guān)



引文:


  1. 內(nèi)存布局
  2. 內(nèi)存管理方案
  3. 數(shù)據(jù)結(jié)構(gòu)
  4. ARC&MRC
  5. 引用計(jì)數(shù)
  6. 弱引用
  7. 自動(dòng)釋放池
  8. 循環(huán)引用
image.png
內(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)快速分流?

image.png
數(shù)據(jù)結(jié)構(gòu)

Spinlock_t (自旋鎖)

Spinlock_t 是一種"盲等"的鎖,(一直循環(huán)去詢(xún)問(wèn)訪問(wèn))

適應(yīng)于輕量的訪問(wèn)

RefcountMap (引用計(jì)數(shù)表)

image.png

weak_table_t (弱引用表)

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

image.png
ARC (自動(dòng)引用計(jì)數(shù))

ARC是LLVMRuntime協(xié)作的結(jié)果

ARC中禁止手動(dòng)調(diào)用retain/release/retainCount/dealloc方法

ARC中新增strongweak屬性關(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
image.png

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

image.png
自動(dòng)釋放池

是以棧為方式的通過(guò)雙向鏈表的形式組合而成的
是和線程一一對(duì)應(yīng)的

編譯器會(huì)將@autoreleasepool{} 改寫(xiě)為:

void *ctx = objc_autoreleasePoolPush();
  // 業(yè)務(wù)邏輯
autoreleasePoolPop(ctx)
AutoreleasePoolPage
image.png

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)型:

  1. 自循環(huán)引用
  2. 相互循環(huán)引用
  3. 多循環(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)解決

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容