Skip to content

2. 谈谈iOS的内存管理方式的理解 #2

@tbfungeek

Description

@tbfungeek

iOS 内存管理是下面三种方式的结合:

  1. 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技术的启用与关闭的决定权交给开发者.

image

  • 所有对象都有 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

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions