这是我参与更文挑战的第6天,活动详情查看: 更文挑战
WWDC 2020
中关于runtime
的优化
在
WWDC 2020
中,Apple
针对Objective-C
的runtime
作出了优化,极大的提高了内存的使用率
Class data structures changes
优化
数据结构的优化,
Objective-C
的runtime
会通过它们来追踪类
在磁盘中,我们App
的二进制文件中的类是这样的
首先这个类对象本身包含了最常被访问的信息:指向元类
、超类
和方法缓存
的指针,它还有一个指向更多数据的指针存储额外信息class_ro_t
:
Ro
表示只读,它包含像是类名字,方法,协议和实例变量的信息,Swift
和Objective-C
类共享这一基础结构,所以没一个Swift
类也有这样的结构
当类
第一次从磁盘加载到内存
中时,一开始它们也是这样的结构,但是一经使用,它们就会发生变化,想要了解这些变化,我们必须先要了解clean memory
和dirty memory
的区别
clean memory
指的是加载后不会发生更改的内存,
class_ro_t
就属于clean memory
,因为它是只读的
dirty memory
指的是在进程运行时会发生更改的内存,类结构一经使用就会变成
dirty memory
,因为运行时会向它写入新的数据。例如创建一个新的方法缓存,并从类中指向它;
dirty memory
比clean memory
要昂贵的多,只要进程在运行,它就必须一直存在;clean memory
可以进行移除,从而节省更多的内存空间,因为如果你需要clean memory
系统可以从磁盘中重新加载;
macOS
可以选择换出dirty memory
,但因为iOS
没有使用swap
,所以dirty memory
在iOS
中代价很大;dirty memory
是一个类数据被分成两部分的原因,可以保持清洁的数据越多越好;通过分离出那些永远不会更改的数据,可以把大部分的类数据存储为clean memory
。
虽然这些数据足以让我们开始,但是运行时需要追踪每个类的更多信息,所以当一个类首次被使用,运行时会为它分配额外的存储容量class_rw_t
,用来读取-编写数据
在class_rw_t
这个数据结构中,我们存储了只有在运行时才会生成的新数据First Subclass
和Next Sibling Class
;例如所有的类都会链接成一个树状结构,这就是通过使用First Subclass
和Next Sibling Class
指针实现的,这允许运行时遍历当前使用的所有类,这对于使方法缓存无效非常有用;但为什么Methods
、Properties
和Protocols
在只读数据class_ro_t
中时,我们class_rw_t
里边还有它们呢?因为它们可以在运行时进行更改,当Category
被加载时,他可以向类中添加新的方法,而且开发者可以使用运行时API动态的添加它们。因为class_ro_t
是只读的,所以我们需要在class_rw_t
中追踪这些东西;然而这样做的结果是我们会占用相当多的内存,在任何给定的设备中都有许多类在使用,Apple
在iPhone
上的整个系统中进行测量,结果显示大约30兆字节
被存储在class_rw_t
结构中,那么我们如何缩小这部分结构呢?
注意,我们在读取-编写数据时需要这些东西,因为它们可以在运行时进行更改,当时通过检查实际设备上的使用情况,Apple
发现大约之后10%
的类真正的更改了他们的方法;而且只有Swift
类才会使用Demangled name
字段,并且Swift
类并不需要这一字段,除非有询问它们的Objective-C
名称时才需要,所以我们可以拆掉平时不用的部分,这将class_rw_t
的大小减少了一半
对于那些确实需要额外信息的类,我们可以分配这些扩展记录中的一个。并把它添加到类中供其使用
大约90%
的类从来不需要这些扩展数据,这些系统范围内可节约大约14MB
的内存,这部分内存我们可用于更有效的途径,比如存储我们的App
的数据
$ heap Mail | egrep 'class_rw|COUNT'
复制代码
以上命令可以帮助我们查看邮件App中使用的class_rw_t
类型的数量,实际上他们中只有10%
需要使用这一扩展信息,基于此,我们很容易计算出通过这个改变所节省的内存:这是大小减半的类型,所以如果我们从这个数字中减去我们必须分配给扩展类型的内存里,我们可以看到,我们节省了大约一兆字节的四分之一,这还只是对于邮件App而言,如果在系统范围内进行扩展对dirty memory
而言这是真正的节省内存
Relative method lists
优化
Objective-C
的方法列表的优化