美文网首页
WWDC-关于 runtime 的优化

WWDC-关于 runtime 的优化

作者: 忻凯同学 | 来源:发表于2021-06-24 17:10 被阅读0次

    前言

    此次优化是 WWDC-2020 提出的,下面可自行观看视频:

    关于 runtime 的改进优化

    用作者话来说,开发者无需更改任何代码,也不使用新的API,应用程序也会变得更快。因为 Apple 在内部运行时做了底层数据结构的优化。

    数据结构的变化(Class Data Structures Changes)

    在磁盘上,在app的二进制文件中,类的结构如下:

    对于类的对象本身,它包含最常访问的信息:

    • 指向元类、超类和方法缓存的指针。
    • 指向存储附加信息的更多数据的指针,称为 class_ro_t。其中 Ro 代表只读。

    class_ro_t 包括类的名称以及方法、协议和实例变量的信息。并且 SwiftObjective-C共享这一基础结构。

    当类第一次从磁盘加载到内存中时,它们一开始是固定的,但是一旦被使用,它们就会改变。为了理解接下来的类的变化,首先了解一下 Clean MemoryDirty Memory

    Clean Memory 和 Dirty Memory

    • Clean Memory 是指加载后不会发生更改的内存。class_ro_t 就是属于 Clean Memory,因为它是只读的。

    • Dirty Memory 是指在进程运行时发生更改的内存。Class 一旦被使用就会变成 Dirty Memory,因为运行时会将新数据写入类中。

    特点:

    Dirty Memory 只要进程在运行,它就一直存在。而且 iOS 不比 macOS 可以选择交换 Dirty MemoryiOS 不使用 swap,所以 Dirty MemoryiOS 中代价很大。

    Clean Memory 可以进行移除,从而节省更多的内存空间。如果你再次需要它,系统可以从磁盘中 重新加载

    这也是 Class 数据被分成两部分的原因,可以保持干净的数据越多越好,分离出不改变的数据,存储为 Clean Memory

    class_rw_t

    虽然这些数据足以使用,但运行时需要跟踪有关每个类的更多信息,因此当类第一次被使用时,运行时还会为它分配额外的存储空间。

    这个运行时分配的存储容量是 class_rw_t,用于读/写数据。在 class_rw_t 中,存储了只有在运行时才会生成的新信息。

    First SubclassNext Sibling Class:由于 class_rw_t 中的 First SubclassNext Sibling Class 的特性,所有类都会链接成一个 树状结构。它们允许运行时遍历当前使用的所有类

    MethodsPropertiesProtocols:在运行时进行添加的,当 Category 被加载时,它可以向类中添加新的方法,也可以通过 Runtime API 动态添加。

    Demangled Name:只有 Swift 才会使用的字段,甚至 Swift 类都不需要它。除非开发者想要访问 SwfitOC 名称,利用率比较低。

    class_rw_t 拆分

    因为 class_rw_t 里面有太多的东西,会占用 很多 的内存。可以将 不常用 的部分拆分,分配到另一个扩展记录以供类使用。

    在实际设备上检查使用情况时,发现只有大约 10% 的类真正改变了 Methods。所以,MethodsPropertiesProtocols 可以被拆分。

    Demangled Name:只有 Swift 才会使用,也可以被拆分。

    因此拆分效果如图:

    class_rw_t 与 class_ro_t 的区别

    • 当类使用了 category 的时候,那么类就有了 class_rw_t 的结构,如果未使用 category,那么类就是一个单纯的 class_ro_t 的结构 (Clean Memory)

    • 反之,在类的内存结构中如果有 class_rw_t 的结构,那么必然会有 category

    案例

    实际验证 XcodeSafariclass_rw_t 占用的内存

    $ heap Xcode | egrep 'class_rw|COUNT'

    占用内存如下:

    Xcode:

    • class_rw_t 占用字节:2877568

    • class_rw_ext_t 占用字节:203664,占比 7%

    Safari:

    • class_rw_t 占用字节:186496

    • class_rw_ext_t 占用字节:27312,占比 15%

    总结:class_rw_ext_t 的拆分,可以节省内存开销。

    相关文章

      网友评论

          本文标题:WWDC-关于 runtime 的优化

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