美文网首页
cache_t分析

cache_t分析

作者: 北京_小海 | 来源:发表于2020-09-18 15:38 被阅读0次

    一、初探cache_t

    1.cache_t结构

    首先找到objc_class

    点击cache进去看看

    太多了 就不都截图了 看看宏定义是什么回事

    CACHE_MASK_STORAGE_HIGH_16 : 真机&&64位

    CACHE_MASK_STORAGE_LOW_4 : 真机&&非64位

    CACHE_MASK_STORAGE_OUTLINED:模拟器和Mac呗

    bucket_t结构

    cache_t中的_buckets、_mask、_occupied从字面意思上理解为桶、面具、占据,但是我们不知道这三个的作用是否与他们的名字有关系,下面我们先从LLDB打印一些信息来看看

    2.lldb调试

    代码准备

    2.1开始调试

    调用sayhello

    我们可以看到想要的东西了(_buckets, _mask, _flags, _occupied)

    内部有很多方法

    通过调用buckets()查看结构

    发现包含sel和imp 看一下源码方法

    调用获取

    2.2多个方法调试

    发现 _occupied有变化,这个我们一会在分析,我们现在先了解 buckets

    找不到saycode

    那我大胆猜一下!buckets有s,那他是不是有多个?,会不会是个类似数组结构?那我通过指针偏移可不可以得到想要的东西?那验证一下呗!

    搞定 现在我们了解了buckets里面存sel和imp了

    二. cache_t实现原理分析

    _occupied如何变化的?而且当方法增多,mask也改变。还有buckets怎么存的?

    看到了incrementOccupied,让我们看看谁调用的

    找到了insert  全局搜索 找到cache_fill

    全局搜索cache_fill,发现在写入之前,还有一步操作,即cache读取,即查找sel-imp,

    本文的重点还是分析cache存储的原理,接下来根据cache_t写入的流程图,着重分析insert方法insert方法分析

    大致分为三步

    第一步:计算出当前的缓存占用量 

    根据occupied的值计算出当前的缓存占用量,当属性未赋值及无方法调用时,此时的occupied()为0,而newOccupied为1,如上图所示

    alloc申请空间时,此时的对象已经创建,如果再调用init方法,occupied也会+1

    当有属性赋值时,会隐式调用set方法,occupied也会增加,即有几个属性赋值,occupied就会在原有的基础上加几个

    当有方法调用时,occupied也会增加,即有几次调用,occupied就会在原有的基础上加几个

    第二步:根据缓存占用量判断执行的操作

    reallocate方法:开辟空间

    该方法,在第一次创建以及两倍扩容时,都会使用,其源码实现如图所示

    allocateBuckets方法:向系统申请开辟内存,即开辟bucket,此时的bucket只是一个临时变量

    setBucketsAndMask方法:将临时的bucket存入缓存中,此时的存储分为两种情况:

    如果是真机,根据bucket和mask的位置存储,并将occupied占用设置为0

    如果不是真机,正常存储bucket和mask,并将occupied占用设置为0

    如果有旧的buckets,需要清理之前的缓存,即调用cache_collect_free方法,其源码实现如下

    该方法的实现主要有以下几步:

    _garbage_make_room方法:创建垃圾回收空间

    如果是第一次,需要分配回收空间

    如果不是第一次,则将内存段加大,即原有内存*2

    记录存储这次的bucket

    cache_collect方法:垃圾回收,清理旧的bucket

    第三步:针对需要存储的bucket进行内部imp和sel赋值

    这部分主要是根据cache_hash方法,即哈希算法 ,计算sel-imp存储的哈希下标,分为以下三种情况: 如果哈希下标的位置未存储sel,即该下标位置获取sel等于0,此时将sel-imp存储进去,并将occupied占用大小加1 如果当前哈希下标存储的sel 等于 即将插入的sel,则直接返回 如果当前哈希下标存储的sel 不等于 即将插入的sel,则重新经过cache_next方法 即哈希冲突算法,重新进行哈希计算,得到新的下标,再去对比进行存储

    cache_hash:哈希算法

    cache_next:哈希冲突算法

    最后将上述流程总结一个流程图

    画图软件用得少 图不太好看 谅解哈~~

    相关文章

      网友评论

          本文标题:cache_t分析

          本文链接:https://www.haomeiwen.com/subject/vfydyktx.html