前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS-内存管理(一)

iOS-内存管理(一)

原创
作者头像
Wilbur-L
修改2020-12-21 10:32:10
9830
修改2020-12-21 10:32:10
举报
文章被收录于专栏:iOS底层原理

一·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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一·Five area
  • 二·targetpointer
    • 1.setter修饰小对象类型
      • 2.initializeTaggedPointerObfuscator
      • 三.targetpointer地址的特殊含义
      • 四·MRC&ARC
        • 1.retain/release
          • 散列表结构
          • 2.dealloc
          • 3.EXTRA_RC操作引用计数
          • 4.carry引用计数表超标
          • 5.retainCount
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档