Tagged pointer和nonpointer

原文链接

产生原因

在 2013 年 9 月,苹果推出了 iPhone5s,与此同时,iPhone5s 配备了首个采用 64 位架构的 A7双核处理器,

为了节省内存和提高执行效率,苹果提出了Tagged Pointer的概念。对于 64 位程序,引入 Tagged Pointer 后,相关逻辑能减少一半的内存占用,以及3 倍的访问速度提升,100倍的创建、销毁速度提升。

64位系统下 有些对象占用内存翻倍

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

TaggedPointer

原理和作用

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

所以我们可以将一个对象的指针拆成两部分,一部分直接保存数据,另一部分作为特殊标记,表示这是一个特别的指针,不指向任何一个地址。

所以,引入了Tagged Pointer对象之后,64 位 CPU 下NSNumber 的内存图变成了以下这样:
在这里插入图片描述

关于taggedpointer

  1. Tagged Pointer是专⻔⽤来存储⼩的对象,例如NSNumber,NSDate等。
  2. Tagged Pointer指针的值不再是地址了,⽽是真正的值。所以,实际上它不再是⼀个对象了,它只是⼀个披着对象⽪的普通变量⽽已。所以,它的内存并不存储在堆中,也不需要malloc和free。
  3. 当指针不够存储数据时,就会使用动态分配内存的方式来存储数据。
  4. 在内存读取上有着3倍的效率,创建时⽐以前快106倍。
    isa_t(uintptr_t value) : bits(value) { } 中,“:”的作用
    位域位域是指信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可。为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。所谓“位域”是把一个字节中的二进位划分为几 个不同的区域, 并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。 这样就可以把几个不同的对象用一个字节的二进制位域来表示。

nonpointer

0

如果nonpointer为0,代表raw isa,也就是没有结构体的部分,访问对象的 isa 会直接返回一个指向 cls 的指针,也就是在 iPhone 迁移到 64 位系统之前时 isa 的类型。

1

如果为1,代表它不是指针,是已经优化的isa,关于类的信息存储在shiftcls中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值