Tagged Pointer 和 nonpointer

2020-06-08  本文已影响0人  梦里桃花舞倾城

前言

20139 月,苹果推出了 iPhone5s,与此同时,iPhone5s 配备了首个采用 64 位架构的 A7双核处理器,为了节省内存和提高执行效率,苹果提出了Tagged Pointer的概念。对于 64 位程序,引入 Tagged Pointer 后,相关逻辑能减少一半的内存占用,以及3 倍的访问速度提升,100倍的创建、销毁速度提升。

问题

我们先看看原有的对象为什么会浪费内存?

假设我们要存储一个 NSNumber对象,其值是一个整数。正常情况下,如果这个整数只是一个 NSInteger的普通变量,那么它所占用的内存是与 CPU 的位数有关,在 32CPU 下占 4个字节,在 64CPU 下是占 8 个字节的。而指针类型的大小通常也是与CPU位数相关,一个指针所占用的内存在 32CPU 下为4 个字节,在 64CPU 下也是8个字节。

所以一个普通的 iOS 程序,如果没有Tagged Pointer对象,从 32 位机器迁移到 64 位机器中后,虽然逻辑没有任何变化,但这种 NSNumberNSDate 一类的对象所占用的内存会翻倍。如下图所示:

01

Tagged Pointer

为了改进上面提到的内存占用和效率问题,苹果提出了Tagged Pointer对象。由于 NSNumberNSDate 一类的变量本身的值需要占用的内存大小常常不需要8个字节,拿整数来说,4 个字节所能表示的有符号整数就可以达到 20 多亿(注:2^31=2147483648,另外 1 位作为符号位),对于绝大多数情况都是可以处理的。

所以我们可以将一个对象的指针拆成两部分,一部分直接保存数据,另一部分作为特殊标记,表示这是一个特别的指针,不指向任何一个地址。所以,引入了Tagged Pointer对象之后,64CPUNSNumber 的内存图变成了以下这样:

02

总结

苹果将Tagged Pointer引入,给64位系统带来了内存的节省和运行效率的提高。Tagged Pointer通过在其最后一个 bit 位设置一个特殊标记,用于将数据直接保存在指针本身中。因为Tagged Pointer并不是真正的对象。

nonpointer

isa

nonpointer

has_assoc

has_cxx_dtor

shiftcls

magic

weakly_referenced

deallocating

extra_rc

has_sidetable_rc

参考链接:巧神:
深入理解Tagged Pointer

上一篇 下一篇

猜你喜欢

热点阅读