Tagger point
管理小對象,NSDate、NSNumber
內(nèi)部的實現(xiàn)?
加密-解密算法,內(nèi)存地址+值,存放常量區(qū)
NONPOINTER_ISA
在64位架構(gòu)下,isa指針占64比特位實際上30多位就夠用,為了提高利用率,剩余的比特位存儲了內(nèi)存管理的相關(guān)數(shù)據(jù)內(nèi)容。
第一位的0或者1 代表是純地址型的isa指針,還是無地址nopointer_isa指針。
第2位代表是否有關(guān)聯(lián)對象
第3位代表是否有c++代碼
接下來33位代表指向的內(nèi)存地址
接下來有弱引用的標記
接下來是否有dealloc的標記
散列表(引用計數(shù)表、弱引用表)
通過SideTables()結(jié)構(gòu)實現(xiàn),在SideTables()結(jié)構(gòu)下,有很多sideTable的數(shù)據(jù)結(jié)構(gòu)。
而sideTable當(dāng)中當(dāng)中包含了自旋鎖,引用計數(shù)表,弱引用表。
SideTables()實際是一個哈希表,通過對象的地址來計算該對象的引用計數(shù)在那個sideTable中
retainCount存儲在這64張sideTable中,通過指針的地址,查找引用計數(shù)的地址,大大提多少效率
內(nèi)存分區(qū)
棧區(qū)、堆區(qū)、全局區(qū)、常量區(qū)、代碼區(qū) 地址由左邊至右邊是高地址到低地址
棧區(qū)-stack
線性數(shù)據(jù)結(jié)構(gòu),向低地址擴展,遵循先入后出,運行時分配
棧區(qū)編譯器自動分配,主要用來存儲局部變量。
棧區(qū)的大小提前分配好,然后棧指針指向空間地址最高處,壓棧數(shù)據(jù)向低地址生長。出棧時,只需將棧指針向高地址移動。
堆區(qū)-heap
不連續(xù)的鏈表結(jié)構(gòu),向高地址擴展,遵循先進先出,一般運行時分配
程序員分配和釋放,OC中alloc、new、copy開辟創(chuàng)建對象
靈活方便,需手動管理,易產(chǎn)生內(nèi)存碎片
當(dāng)需要訪問堆中內(nèi)存,一般需要先通過對象讀取到棧區(qū)的指針地址,然后通過指針地址,訪問堆區(qū)。
全局區(qū)(靜態(tài)區(qū))
bss段:
通常存放程序中未初始化的或者初始值為0的全局變量一塊內(nèi)存區(qū)域。block srart by symbol的簡稱。bss段數(shù)據(jù)靜態(tài)內(nèi)存分配
數(shù)據(jù)段:
用來存放程序中已初始化全局變量的一塊內(nèi)存區(qū)域,也屬于靜態(tài)內(nèi)存分配
static修飾的變量會成為靜態(tài)變量,該變量的內(nèi)存由全局/靜態(tài)區(qū)在編譯階段完成,且分配一次 static可修飾全局變量和局部變量。
常量區(qū)
通常存儲已初始化的全局變量和靜態(tài)變量的一塊內(nèi)存區(qū)域。
代碼區(qū)
編譯時分配主要用于存放程序運行時代碼,代碼會編譯成二進制內(nèi)存, 代碼區(qū)要防止運行時被修改,因此是可讀,不允許寫入