前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >OC-类的内存结构-cache

OC-类的内存结构-cache

原创
作者头像
Wilbur-L
修改2020-12-11 10:27:04
8300
修改2020-12-11 10:27:04
举报

一·如何找到内存的结构

所有的一切都建立在苹果开源的源码上,所以明白我们研究的是什么,类-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()

mask
mask

6.mask_t occupied()

occupied
occupied

7.void incrememtOccupied()

占位函数
占位函数

8.capacity()

容量
容量

9.rellocate()

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

allocateBuckets
allocateBuckets

为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赋值

setbucketandmask
setbucketandmask

初始化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结构当中的点睛之笔。

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一·如何找到内存的结构
  • 二·关键词
    • 1._maskandBucketsmask_t
      • 2.maskuint_16_t _flagsmask16_t
        • 3.-occupied
          • 4.struct bucket_t buckets()
            • 5.mask_t mask()
              • 6.mask_t occupied()
                • 7.void incrememtOccupied()
                  • 8.capacity()
                    • 9.rellocate()
                      • 10.insert()
                      • 三·化元归一(总结)
                        • 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分之二:若容量为默认则进入到申请内存空间步骤
                                    • 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结构当中的点睛之笔。
                                    领券
                                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档