一、內(nèi)存布局
二、內(nèi)存管理方案
1. TaggedPointer
對(duì)于小對(duì)象比如NSNumber,采用這種方案。
2. NONPOINTER_ISA
在64位架構(gòu)下的isa指針是64bit位,實(shí)際上33位就能夠表示類(lèi)對(duì)象(或元類(lèi)對(duì)象)的地址,為了提供內(nèi)存的利用率,在剩余的bit位當(dāng)中添加了內(nèi)存管理的數(shù)據(jù)內(nèi)容。


主要位的介紹:
1.第一位index位,表示該isa指針是否是NONPOINTER_ISA指針。如果是0表示為pointer類(lèi)型的指針,即該指針的64位值表示的就是類(lèi)對(duì)象的地址。
2.第二位has_assoc,表示是否有assoc關(guān)聯(lián)對(duì)象。
3.shiftcls一共33位,表示類(lèi)對(duì)象的內(nèi)存地址。
4.weakly_referenced位,表示該對(duì)象是否有弱引用指針。
5.最后的extra_rc位,可以存儲(chǔ)引用計(jì)數(shù),如果引用計(jì)數(shù)的值很小,則通過(guò)它來(lái)存儲(chǔ),如果超過(guò)了它范圍,則會(huì)通過(guò)sidetables引用技術(shù)標(biāo)來(lái)存儲(chǔ)
6.has_sidetable_rc位,表示是否有散列表。
3. 散列表SideTables()
3.1 SideTables()

SideTables()實(shí)際是一個(gè)哈希表,我們可以通過(guò)對(duì)象指針,找到所對(duì)應(yīng)的引用計(jì)數(shù)表或弱引用表位于哪個(gè)SideTable表中。也就是有多個(gè)sideTable表。
知識(shí)點(diǎn)1:為什么不是一個(gè)大表,而是多個(gè)表?
回答:如果只有一張表,所有對(duì)象的引用計(jì)數(shù)都放到一張表中,則如果在修改某個(gè)對(duì)象的引用計(jì)數(shù)的時(shí)候,由于對(duì)象可能在不同線程中被操作,則需要對(duì)表進(jìn)行加鎖,這樣一來(lái),效率就會(huì)極地。
知識(shí)點(diǎn)2:什么是哈希表

通過(guò)hash函數(shù)可以快速通過(guò)key值,得到所對(duì)應(yīng)的數(shù)組當(dāng)中的索引位置。賦值和獲取都避免了遍歷,提高了效率。
3.2 SideTable結(jié)構(gòu)

我們可以看到,SideTable是有三部分組成:
3.2.1 Spinlock_t自旋鎖
- 是一種“忙等”的鎖,如果鎖已被其他線程獲取,則當(dāng)前線程會(huì)不斷探測(cè)鎖,如果探測(cè)到鎖被釋放,則獲取鎖。
- 適用于輕量訪問(wèn)。比如引用計(jì)數(shù)的修改。
3.2.2 引用計(jì)數(shù)表

引用計(jì)數(shù)表也是一個(gè)hash表,通過(guò)hash函數(shù)找到指針對(duì)應(yīng)的引用計(jì)數(shù)的位置。
下面來(lái)看size_t的具體內(nèi)容:

3.2.3 弱引用表

弱引用表也是一個(gè)hash表,通過(guò)hash函數(shù)找到對(duì)象對(duì)應(yīng)的弱引用數(shù)組。