OC-类的内存结构-cache

2020-12-11 10:27:04 浏览数 (1)

一·如何找到内存的结构

所有的一切都建立在苹果开源的源码上,所以明白我们研究的是什么,类-class

oc里的类统统都来自一个结构体 objc_class

以这个为切入点,我们可以尝试在源码层搜索objc_class {

类一级结构类一级结构

二·关键词

方法论:由于内存结构代码量太大

cache_t 的结构长达200多行,若干个相关变量

那么楼主打算从每个关键词出发从"点-线-面"的思维方式来研究对象。(既从微观研究到宏观,然后得出一个整体思路)

理解这一点很重要,不然会看不懂接下来贴了一大堆的图片究竟是为了什么。

1._maskandBucketsmask_t

节省内存的一种算法节省内存的一种算法

2.maskuint_16_t _flagsmask16_t

3.-occupied

4.struct bucket_t buckets()

桶

5.mask_t mask()

maskmask

6.mask_t occupied()

occupiedoccupied

7.void incrememtOccupied()

占位函数占位函数

8.capacity()

容量容量

9.rellocate()

rellocate-内存二级函数rellocate-内存二级函数

allocateBucketsallocateBuckets

为newCapacity calloc一片空间

缓存回收缓存回收

释放旧bucket,赋值新的bucket,执行缓存回收函数

garbage 通常会把data数据放在寄存器的x16 x32类似的位置来处理,而不会放在高位x0等等,防止x0~x8有数据。

10.insert()

插入内存函数片段-1插入内存函数片段-1
插入内存函数片段-2插入内存函数片段-2
那么insert函数做了以下几件事情

1.初始化occupied() 1

2.判断容量大小

3.设置缓存的哈希头标识index

哈希哈希

4.判断缓存的下一个节点是否是begin头 如果是给bucket的sel和imp赋值

setbucketandmasksetbucketandmask

初始化occupied=0

缓存收集函数缓存收集函数

释放缓存

三·化元归一(总结)

1.从objc_class得到cache_t

2.在真机下cache_t拥有者若干有用变量及函数

3.maskandBuckets 是通过逻辑位运算合并到一块的,目的是为了节约内存

4.缓存判断会先经过cache_fill 填充判断(Never cache before initialize is done)

5.缓存插入会计算当前缓存占用数量既occupied 1

6.判断缓存大小会有三个不同的分支

6.1分支一:若容量小于3/4什么都不做

6.2分之二:若容量为默认则进入到申请内存空间步骤

1.allocatedBucket()

2.setBucketsAndMask:根据newMask <<maskShift | newBuckets

3.occupied=0

4.如果有旧的bucket,执行释放缓存garbage_make_room & garbage_refs[garbage_count ]=data

6.3分支三:若容量大于3/4会进行三目运算判断扩容 :cap=cap?cap*2 :init_cache_size

6.4分支四:针对这一次要存储的bucket进行内部的sel和imp赋值 既赋值操作从x30后开始,保留x0~x8

7.缓存cache_t中最重要的一点思想就是:"扣"。苹果为了节约内存甚至把bucket和mask合并到了一起

从而2-1的maskandbucket是缓存cache结构当中的点睛之笔。

0 人点赞