Skip to content

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

Open
@tbfungeek

Description

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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