Open
Description
iOS 内存管理是下面三种方式的结合:
- Tagged Pointer
- Tagged Pointer专门用来存储例如NSNumber和NSDate的小对象数据,这种数据绝大多数4字节都够满足需求了,在64位系统下就会造成极大的浪费,所以它会将值存在Tagged Pointer,而不是将它作为一个地址,值另外存储,它的内存并不存储在堆中,不需要malloc和free,可以极大得提高创建和读写效率。并且节省内存空间。 总的来说它就是为了节省内存和提高效率。
引入 Tagged Pointer 后,相关逻辑能减少一半的内存占用,以及 3 倍的访问速度提升,100 倍的创建、销毁速度提升。
我们分别来看下使用Tagged Pointer之前和之后的对比:
-
Tagged Pointer 将一个对象的指针拆成两部分,一部分直接保存数据,另一部分作为特殊标记,表示这是一个特别的指针,不指向任何一个地址.
-
苹果预留了环境变量OBJC_DISABLE_TAGGED_POINTERS,通过设置该变量的布尔值,可以将Tagged Pointer技术的启用与关闭的决定权交给开发者.
- 所有对象都有 isa 指针,而Tagged Pointer其实是没有的,因为它不是真正的对象。所以在使用的时候要注意不要直接访问其 isa 变量。
例子:
NSNumber *number1 = @1;
NSNumber *number2 = @2;
NSNumber *number3 = @3;
NSNumber *number4 = @999999999999999999;
IDLLogError(@"=======>%p",number1);
IDLLogError(@"=======>%p",number2);
IDLLogError(@"=======>%p",number3);
IDLLogError(@"=======>%p",number4);
输出结果:
[❤️ IDL_Error]:2019-12-30 23:38:07 DefaultModule IDLObject [32] -[IDLObject increase] :=======>0xd3d04d740e528d8b
[❤️ IDL_Error]:2019-12-30 23:38:07 DefaultModule IDLObject [33] -[IDLObject increase] :=======>0xd3d04d740e528dbb
[❤️ IDL_Error]:2019-12-30 23:38:07 DefaultModule IDLObject [34] -[IDLObject increase] :=======>0xd3d04d740e528dab
[❤️ IDL_Error]:2019-12-30 23:38:07 DefaultModule IDLObject [35] -[IDLObject increase] :=======>0x600003e07740
Metadata
Metadata
Assignees
Labels
No labels
Activity