自动释放池

objc下层c++代码

生成c++代码查看

  • clang -rewrite-objc main.m -o main.cpp
  • 脚本直接直接配置到测试工程里

在这里插入图片描述
脚本直接生成c++代码 并打开
在这里插入图片描述
选择脚本 build,xcode直接弹窗打开c++代码
在这里插入图片描述

查找autorelease相关c++代码

在这里插入图片描述

  • 全局查找 __AtAutoreleasePool 是个结构体

在这里插入图片描述
其实说白了就是结构体(自动释放池)构造,析构

其实说白了就是结构体(自动释放池)构造,析构

  • 自动释放池作用域调整下代码

在这里插入图片描述
构造 objc_autoreleasePoolPush() 压栈

析沟 objc_autoreleasePoolPop(void *) 弹出栈

根据c++代码分析大致了解到,自动释放池其实就是一块作用域时机,作用域开始时构造,作用域结束时析构回收 主要是个栈结构

汇编查看

在这里插入图片描述
在这里插入图片描述
通过汇编,结果更直观,压栈,执行逻辑, 出栈

汇编 进入符号 objc_autoreleasePoolPush 最终得到符号所在的dyld

在这里插入图片描述
发现 objc_autoreleasePoolPush 符号存在于objc源码中,所以我们进入源码

没有源码环境?快速配置一个出来

打开源码调试工程

查找符号 objc_autoreleasePoolPush

在这里插入图片描述
在这里插入图片描述

  • 如果就这样分析,还是一股脑儿就是代码,没什么直观意识,能查看到具体结构信息最好

    关闭arc

在这里插入图片描述

既然提到了打印信息,那么就看源码里有没有相关的调试打印函数,既然有调试,应该会有,拿来用就可以了

前后多看些范围代码,发现了打印函数

在这里插入图片描述
既然C函数,我们可以声明extern来使用
在这里插入图片描述

  • 编译运行

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
非arc下,autorelease - 对象才会放入池子

  • 如果加个循环

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这时候 其实可以看出关键点了 根据打印逻辑回看源码

AutoreleasePoolPage: AutoreleasePoolPageData

在这里插入图片描述

可以看出是个双向链表 (nil <- page <-> page <-> page <-> page -> nil)

在这里插入图片描述

AutoreleasePoolPage: push()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

释放池push操作 分析一下

  • 释放池是分页设计,就像内存分页概念一样,如果不分页,一下子要面对池子里的一坨很大的数据,人是无法处理超级多的复杂的事情的,这儿自动释放池也一样

  • 不分页的设计会造成池子里对象么次操作 都需要检索整个池子,而池子对象可能很多,效率不高

  • 只有分页对于栈式结构来说,每次操作只在有限长度栈结构内,超过就一页一页pop,之前被压在hot页下面的不活动页变成hot,每次操作只需要检索一小块数据对象

  • 对于嵌套释放池,不分页设计就没有了渐进式内存处理,池子要么整个内存,要么整个释放,但其实从应用逻辑业务角度来看,用户的操作是一个一个访问具体功能,分页才更合理

  • 自动释放池整体可以理解为两层栈结构

    • 外层把一个个page看作一个个单元,page压栈出栈的过程,page大小是固定的,顶层的page为活动的page,也就是当前操作的page

    • page内部也是一个栈结构,object压栈出栈,object可能是常规对象,也可能是边界,用于区分是不是嵌套了池子

    • 池子可能跨越了多个page,也可能就在一个page里,不重要,看边界在哪儿

分析page大小

根据上面的1024次循环 构建1024个对象,打印结果出现两次 page full标识,也就是有3页,两个满页

hot page未满,有15个对象

也就是说每个page ((1024-15) + 1) / 2 = 505 个对象(每个对象指针8字节)【+1是因为还有一个边界8字节】

505 * 8 = 4040字节 ---- 4k == 4096字节 ----- 差56字节? 差在了哪儿?
在这里插入图片描述

在这里插入图片描述

可以理解为 每个page有一个magic_t 结构的头,占用16字节 page大小4k得证

自动释放池嵌套

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

自动释放池扩展

在这里插入图片描述
没有autorelease,对象并没有进入释放池 当前是在非ARC下

现在切回ARC

在这里插入图片描述
其实 alloc new copy multablecopy相关前缀 在llvm编译期间不会加入到释放池

自动释放池 pop操作与push相反,就不赘述了, 简单来讲就是 从hotpage开始遍历release对象,然后page->parent 找到code page设置为hot page,当前hotpage kill

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值