内存管理相关

183 阅读2分钟

1. 内存布局

  • stack:栈区,方法调用
  • heap:堆区,通过alloc等分配的对象
  • bss:未初始化的全局变量、静态变量
  • data:已初始化的全局变量等
  • text:程序代码段

2. 内存管理

1. 基础概念
  • TaggedPointer(小对象)

  • NONPOINTER_ISA

  • 散列表(引用计数表、弱引用表)

    • SideTables()结构
    • SideTable结构
  • 如何实现快速分流(定位SideTable)

    • SideTables本质是一张Hash表

    • 涉及到的数据结构

      • 自旋锁-Soinlock_t

        • 是“忙等”的锁
        • 适用于轻量访问
      • 引用计数表-RefcountMap

        • size_t
      • 弱引用表-weak_table_t

2. MRC与ARC
  • MRC-手动引用计数

  • ARC-自动引用计数

    • ARC是LLVM编译器和Runtime协作的结果
    • 禁止手动调用retain/release/retainCount/dealloc
    • 新增weak、strong属性关键字
  • 引用计数管理

    • alloc
      • 实现
        • 经过一系列调用,最终调用c函数的calloc
        • 此时并未设置引用计数为1
    • retain
      • 实现
        SideTable& table = SideTables()[this];
        size_t& refcntStorage = table.refcnts[this];
        refcntStorage += SIDE_TABLE_RC_ONE;
        
    • release
      • 实现
        SideTable& table = SideTables()[this];
        RefcountMap::iterator it = table.refcnts.find(this);
        it->second -= SIDE_TABLE_RC_ONE;
        
    • retainCount
      • 实现
        SideTable& table = SideTables()[this];
        size_t refcnt_result = 1;
        RefcountMap::iterator it = table.refcnts.find(this);
        refcnt_result += it->second >> SIDE_TABLE_RC_ONE;
        
    • dealloc
      • 实现流程
        • object_dispose()实现
          • objc_destructInstance()
            • clearDeallocating()
  • 弱引用管理

    添加weak指针
    清除weak指针

  • 自动释放池

    • 以栈为节点通过双向链表的形式组合
    • 和线程一一对应
    • 多层嵌套就是多次插入哨兵对象
// array的释放时机
- (void)viewDidLoad {
    [super viewDidLoad];
    NSMutableArray *array = [NSMutableArray array];
    NSLog(@"%@", arrar);
}
在当次runloop将要结束的时候调用AutoreleasePoolPage::pop()
  • 实现原理

    • AutoreleasePoolPage
    • AutoreleasePoolPage::pop
      • 根据传入的哨兵对象找到对应位置
      • 给上次push操作之后添加的对象以此发送release消息
      • 回退next指针到正确位置
3. 循环引用
  • 代理

  • Block

  • NSTimer

  • 大环引用

  • 解决

    • 主动避免
    • 在合适的时机断环
  • 方案

    • __weak
    • __block
      • MRC下,__block修饰对象不会增加引用计数,避免了循环引用
      • ARC下,__block修饰对象会被强引用,需要手动解环
    • __unsafe_unretained

3. Block

1. 什么是Block
  • 是将函数及其执行上下文封装起来的OC对象
2. 捕获变量

打印:12

  • 局部变量
    • 基本数据类型
      • 截获其值
    • 对象类型
      • 连同所有权修饰符一起截获
  • 静态局部变量
    • 以指针形式截获
  • 全局变量
    • 不截获
  • 静态全局变量
    • 不截获
3. __block修饰符

  • 对变量进行赋值

  • __block修饰的变量变成了对象

    • __forwarding
      • 不论在任何位置,都可以顺利访问同一个__block变量
  • blcok类型

    • _NSConcreteGlobalBlock - 全局
    • _NSConcreteStackBlock - 栈
    • _NSConcreteMallocBlock - 堆

4. block循环引用