美文网首页
底层原理01:内存管理

底层原理01:内存管理

作者: 春风依旧 | 来源:发表于2019-08-19 22:40 被阅读0次

    一、内存布局

    内存布局.png
    • 代码段(_TEXT):程序代码
    • 数据段(_DATA):
    * 字符串常量:比如NSString *str = @"123";
    * 已初始化数据(data):已初始化的全局变量等 
    * 未初始化数据(bss):未初始化的全局变量等 
    
    • 栈(stack):函数调用开销,比如局部变量。分配的内存空间地址越来越小
    • 堆(Heap):通过alloc、malloc、calloc等动态分配的空间,分配的内存空间地址越来越大

    二、深拷贝和浅拷贝

    深拷贝:内存拷贝
    浅拷贝:指针拷贝

    copy与mutableCopy.png

    集合类深拷贝通过归档、解档实现

    三、MRC & ARC

    MRC:

    alloc, retain , release, retainCount autorelease, dealloc

    ARC(自动引用计数):

    • ARC 是LLVM和Runtime协作的结果
    • ARC中禁止手动调用alloc/retain/release/retainCount/dealloc
    • ARC中新增了weak,strong属性关键字

    四、内存管理方案

    1、TaggedPointer:

    * 用于优化NSNumber、NSDate、NSString等小对象的存储
    * 在没有使用Tagged Pointer之前, NSNumber等对象需要动态分配内存、维护引用计数等,NSNumber指针存储的是堆中NSNumber对象的地址值
    * 使用Tagged Pointer之后,NSNumber指针里面存储的数据变成了:Tag + Data,也就是将数据直接存储在了指针中
    * 当指针不够存储数据时,才会使用动态分配内存的方式来存储数据
    * objc_msgSend能识别Tagged Pointer,比如NSNumber的intValue方法,直接从指针提取数据,节省了以前的调用开销
    * 如何判断一个指针是否为Tagged Pointer?
       iOS平台,最高有效位是1(第64bit)
       Mac平台,最低有效位是1
    

    2、NONPOINTER_ISA(64位系统下)

    * nonpointer
       0:代表普通的指针,存储着Class、Meta-Class对象的内存地址,
       1:代表优化过,不仅有类对象的地址,还有些内存管理方面的数据
    * has_assoc:代表是否有关联对象,如果没有,释放时会更快
    * has_cxx_dtor:是否有 C++ 代码,如果没有,释放时会更快
    * shiftcls:存储着Class、Meta-Class对象的内存地址信息
    * magic:用于在调试时分辨对象是否完成初始化
    * weakly_referenced:是否有弱引用标记,如果没有,释放时会更快
    * deallocating:对象是否正在释放
    * has_sidetable_rc:
          1、0表示引用计数是否过大无法存储在isa中
          2、1表示应用计数存储在sizetable数据结构中(散列表)
    * extra_rc: 额外的引用计数,当引用计数比较小的时候存储在这个地方,而不是存储在散列表中
    

    3、散列表(引用计数表、weak表)

    * SideTables表在非嵌入式的64位系统中,有 64张 SideTable 表
    * 每一张 SideTable 主要是由三部分组成。
      1、Spinlock_t(自旋锁)
      2、RefcountMap(引用计数表)
      3、weak_table_t(弱引用表)
    

    为什么不是一个SideTable,二是一个SideTables组成的结构呢?

     * 一张表,一个是效率问题,一个是多线程资源竞争问题
     * 分离锁:将一张表分拆成多个表,对他们分别加锁,可以实现并发操作,提升执行效率
    

    怎么实现快速分流?

    SideTables的本质是一张Hash表: 哈希表.png
    给定对象内存地址,对哈希的值进行求余操作,目标是SideTables的数组的下表索引
    

    Spinlock_t(自旋锁):

      * 是 “忙等” 的锁
      * 适用轻量访问
    

    RefcountMap(引用计数表):

    是用哈希表实现的,目的是提高查找效率,插入或获取是通过同一个函数来实现的
    size_t: 
      * 第一位weakly_referenced: 是否有弱引用
      * 第二位deallocating:对象是否在dealloc
      * 其他的是值实际的引用计数值。
    

    weak_table_t(弱引用表):


    弱引用技术表.png
    是用哈希表实现的,目的是提高查找效率,插入或获取是通过同一个函数来实现的
    

    相关文章

      网友评论

          本文标题:底层原理01:内存管理

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