【 iOS重学】class_rw_ext_t结构详解
写在前面
在iOS重学之窥探Class的结构这篇文章中,我们分析Class的结构时提到了一个结构class_rw_ext_t
,本文主要就这个结构来展开做个详细的分析,以及苹果为什么要这么做。
class_rw_ext_t结构
简单介绍
在WWDC2020中苹果介绍对类的修改时出现了一个新的结构:class_rw_ext_t
,这个结构主要是Runtime在内存上做的一些优化而出现的,在苹果源码objc4_781版本开始出现class_rw_ext_t
,大家也可以对照源码来阅读本文。
clean memory 和 dirty memory
clean memory:加载后不会再发生变化的内存。
dirty memory:指的是在进程运行时会发生更改的内存。
class_rw_t 和 class_ro_t
在class_rw_ext_t
结构之前,整体Class 结构是:
从上面的结构我们可以看到Class结构被拆分为两部分:class_rw_t
和 class_ro_t
,这么拆分的原因就是为了保持更多的clean memory,从而节省内存空间,其中class_rw_t
是dirty memory,而class_ro_t
就是clean memory。
在class_rw_ext_t
结构之后,整体Class结构是:
从上面的结构图看到:苹果尽可能的减少dirty memory的大小来降低内存开销。他把Methods
、Properties
、Protocols
、Demangled Name
拆分到新的结构class_rw_ext_t
中,这里的ext
可以理解为extension(扩展)。
验证内存变化
使用命令heap xxx | egrep 'class_rw|COUNT'
来查看一些进程中class_rw
类的内存情况,博主这里以微信和Xcode为例来看看:
从上图看到:
WeChat中一共有6418个class_rw_t
类,但是真的需要额外扩展class_rw_ext_t
的只有474个,这个比例大概是7%,我们大概计算一下节省的内存:(6418 - 474) * 48 = 285312(B)。
Xcode中一共有15674个class_rw_t
类,但是真的需要额外扩展class_rw_ext_t
的只有2375个,这个比例大概是15%,节省的内存:(15674 - 2375) * 48 = 638352(B)。
对dirty memory而言,这是真正节省的内存,所以这个优化还是很可观的。
查找方法的变化
在class_rw_ext_t
结构之前,runtime是直接遍历class_rw_t
中的方法列表来查找方法,具体如下图:
在class_rw_ext_t
结构之后,runtime查找方法的方式如下图:
写在最后
关于class_rw_ext_t
结构的分析和好处我们就分析到这里了,如果有什么不对的地方望指教。