美文网首页iOS 开发 Objective-C
iOS 底层 day24 内存管理 内存布局 Tagged Po

iOS 底层 day24 内存管理 内存布局 Tagged Po

作者: 望穿秋水小作坊 | 来源:发表于2020-09-22 17:42 被阅读0次

    一、iOS 程序内存布局

    1.重点掌握下图,我们可以理解很多东西
    内存布局图
    2. 通过下面代码,强化我们的理解
    void func(){    //代码区
        printf("func");
    }
    const int a = 10;   //常量区
    int c = 20; //全局数据区
    int main() {
        NSString *b = @"我是chinese"; // 字符串在常量区; &b在栈区
        static int d = 30;  //全局数据区
        NSObject *e = [[NSObject alloc] init];//对象在堆区; &e在栈区
        NSLog(@"%p",func);
        NSLog(@"\na=%p\nb=%p\nc=%p\nd=%p\ne=%p\n&e=%p\n", &a, b, &c, &d, e, &e);
    }
    

    二、Tagged Pointer

    1. Tagged Pointer基本介绍
    • 64bit 开始,iOS 引入了 Tagged Pointer 技术,用于优化 NSNumber、NSDate、NSString 等小对象的存储
    • 在没有使用 Tagged Pointer 之前,NSNumber 等对象需要动态分配内存、维护引用计数器等,NSNumber 指针存储的是堆中 NSNumber 对象的地址值
    • 使用 Tagged Pointer 之后,NSNumber 指针里面存储的数据变成了:Tag+Data,也就是将数据直接存储在了指针中
    • 当指针不够存储数据时,才会使用动态分配内存的方式来存储数据
    • objc_msgSend 能识别 Tagged Pointer,比如 NSNumberintValue 方法,直接从指针提取数据,节省了以前的调用开销
    2. 如何判断一个指针是否为 Tagged Pointer
    • iOS 平台,指针最高有效位是 1(第 64bit)
    • Mac 平台,指针最低有效位是 1
    3. Tagged Pointer 从代码中窥探它们
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        
        NSNumber *a = @1;
        NSNumber *b = @2;
        NSNumber *c = @(2020202020202002022);
        NSLog(@"%p,%p,%p",a,b,c);
        
        NSString *aa = [NSString stringWithFormat:@"123abc"];
        NSString *aa2 = [NSString stringWithFormat:@"123abc"]; // 发现 aa2 的地址值和 aa 是相同的
        NSString *bb = [NSString stringWithFormat:@"abcd"];
        NSString *cc = [NSString stringWithFormat:@"abcabcabcabcabcabcabcabc"];
        NSLog(@"%p,%p,%p,%p",aa,aa2,bb,cc);
        NSLog(@"%@,%@,%@", [aa class], [bb class], [cc class]);
    }
    
    • 输出
    Demo[5902:460945] 0xb8736ae365a09e56,0xb8736ae365a09e66,0x600000b6cfa0
    Demo[5902:460945] __NSCFNumber,__NSCFNumber,__NSCFNumber
    Demo[5902:460945] 0xa8755cc57693bd52,0xa8755cc57693bd52,0xa8736ae52396b850,0x60000059ef40
    Demo[5902:460945] NSTaggedPointerString,NSTaggedPointerString,__NSCFString
    
    • 我们可以从代码中看出:
    • 当字符串够短,能够用指针存下时,OC 就不会创建堆对象,而是使用 Tagged Pointer 技术来表示
    • 两个内容相同的 Tagged Pointer ,他们的指针也是一摸一样的。
    • Tagged Pointer 的地址最高位都是 0b1

    相关文章

      网友评论

        本文标题:iOS 底层 day24 内存管理 内存布局 Tagged Po

        本文链接:https://www.haomeiwen.com/subject/pcewyktx.html