iOS-内存管理(一)

2020-12-21 10:32:10 浏览数 (1)

一·Five area

stack:function

heap: which is created objc and block by alloc will store in heap area

bss:uninit-var static

data:init-var static

text:coding word which will inject in mem

二·targetpointer

1.setter修饰小对象类型

objc_retain/release{

if(!obj) return obj;

if(obj->isTaggedPointer()) return obj;

return obj->retain/release()

}

解决过渡释放的方法之一,直接返回对象,不返回retain/release

2.initializeTaggedPointerObfuscator

Pull random data into the variable ,then shift away all non-payload bits

将随机数据拉入变量,然后移出所有非有效负载位

arc4random_buf(&objc_debug_taggedpointer_obfuscator)

objc_debug_taggedpointer_obfuscator &= ~_OBJC_TAG_MASK;

与等于 MASK取反

return ptr ^ objc_debug(taggepointer_obfuscator)

return ptr ^ objc_enbug(taggepointer_obfucasor)

小对象的指针地址 通过了1.decode 异或一次 2.encode异或二次

也就是说targetpointer的地址 通过异或一次掩饰过后的地址就可以得到

三.targetpointer地址的特殊含义

targetpointer我们先把它简称为PT

_OBJC_TAG_MASK(1UL<<63)

mask保留了最高位的值0xb

拿到最高位的地址再做一次判断是否为taggetpointer

0xa :string 1 010

0xb :int 1 011

剩下的位置为tag的类型标识码

//60-bit payloads

OBJC_TAG_NSAtom =0,

OBJC_TAG_1 =1,

OBJC_TAG_NSString =2,

OBJC_TAG_NSNumber =3,

OBJC_TAG_NSIndexPath=4,

OBJC_TAG_NSManagedObjectID=5,

OBJC_TAG_NSDate =6,

作用:可以由系统自动回收,自动管理

字符串范围字串

<8

[8,10)

[10,11]

>11

eilotrm,apdnslc

TP

TP

TP

OC

eilotrm,apdnslC4013 & UL20856P

TP

TP

OC

OC

128个ASCII

TP

OC

OC

OC

四·MRC&ARC

1.retain/release

如果不是nonpointerisa 直接操作散列表

散列表结构

spinlock_t slock;

RefcountMap refcnts;

weak_table_t weak_table;

在内存里面有多少张散列表,最大值和最小值分别是什么?

散列表实际上是一张哈希表,结合了两种数据结构(数组链表),既方便查找,又方便插入

IPhone 有8张,其他64张

2.dealloc

objc_object::rootDealloc(){

if(fastpath(isa.nonpointer &&

!isa.weakly_referenced &&

!isa.has_assoc &&

!isa.has_cxx_dtor&&

!isa.has_sidetable_rc

)

析构:1.cxx析构 2.关联对象释放 3.弱引用表析构 4.散列表析构

{

asert(!sidetabel_present());

free(this);

}

最后才free()

}

3.EXTRA_RC操作引用计数

RC_ONE(1ULL<<45)

RC_HALF(1ULL<<18)

结合isa的64位结构的存储数据不同,若需要对引用计数处理,必须先找到头位

newisa.bits=addc(newisa.bits,RC_ONE,0,&CARRY);//extra_rc

4.carry引用计数表超标

如果引用计数表满了

newisa.extra_rc=RC_HALF

那么extra_rc 分开一半

RC_HALF 一般给 extra_rc

RC_HALF 另外一半给sidetable_addExtraRC_nolock(RC_HALF)

5.retainCount

if(bits.nonpointer){

rc=1 bits.extra_rc; //alloc 创建的引用计数为0

if(bits.has_sidetable_rc){

rc = sidetable_getExtraRC_nolock();

}

sidetable_unlock()

return rc

}

默认返回为1

0 人点赞