iOS【进阶】性能优化(上篇)

一、内存五大区

内存区域

特点

栈区

由编译器自动完成分配和释放,不需要程序员手动管理,主要存储了函数的参数和局部变量值等

堆区

需要程序员手动开辟并管理内存(OC有ARC,OC对象通常不需要程序员考虑释放问题)

BSS段(全局区)(静态区)

程序运行过程内存的数据一直都在,程序结束后由系统释放

常量区(数据段)

专门用于存放常量,程序结束后由系统释放

程序代码区

用于存放程序运行时的代码,代码会被编译成二进制存进内存的程序代码区

下面我们来用代码验证一下:

 1 #import <UIKit/UIKit.h>
 2 #import "AppDelegate.h"
 3 
 4 // BSS段
 5 int g1;
 6 static int s1 ;
 7 
 8 //数据段
 9 int g2 = 0;
10 static int s2 = 0;
11 
12 int main(int argc, char * argv[]) {
13     @autoreleasepool {
14         
15         //栈区
16         int i = 10;
17         int j = 10;
18         NSObject *objc = [NSObject new];
19         
20         NSLog(@"%p",&i);  
21         NSLog(@"%p",&j);
22         NSLog(@"%p",&objc);
23         
24         
25         //堆区
26         NSObject *obj1 = [NSObject new];
27         NSObject *obj2 = [NSObject new];
28         NSObject *obj3 = [NSObject new];
29         
30         NSLog(@"%p",obj1);
31         NSLog(@"%p",obj2);
32         NSLog(@"%p",obj3);
33         
34         
35         //BSS段
36         NSLog(@"%p",&g1);
37         NSLog(@"%p",&s1);
38         
39         
40         //数据段
41         NSLog(@"%p",&g2);
42         NSLog(@"%p",&s2);
43         
44         
45         return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
46     }
47 }

打印结果:

2018-09-21 14:14:21.841008+0800 内存管理[1837:252099] 0x7fff527b711c // int 4个字节

2018-09-21 14:14:21.842005+0800 内存管理[1837:252099] 0x7fff527b7118 // int 4个字节

2018-09-21 14:14:21.842269+0800 内存管理[1837:252099] 0x7fff527b7110 // 指针 8个字节

2018-09-21 14:14:21.842630+0800 内存管理[1837:252099] 0x60400001f2e0

2018-09-21 14:14:21.842829+0800 内存管理[1837:252099] 0x60400001f360

2018-09-21 14:14:21.843044+0800 内存管理[1837:252099] 0x60400001f320

2018-09-21 14:14:21.843236+0800 内存管理[1837:252099] 0x10d44afcc

2018-09-21 14:14:21.843410+0800 内存管理[1837:252099] 0x10d44afd0

2018-09-21 14:14:21.843548+0800 内存管理[1837:252099] 0x10d44afc8

2018-09-21 14:14:21.843698+0800 内存管理[1837:252099] 0x10d44afd4

总结:

(1)栈区和堆区是运行时分配的内存,其他区是编译时分配的;

(2)栈区的地址是连续的,并且是由高到低分配的;

(3)堆区的地址是不连续的,堆区的访问速度没有栈区快,堆区的地址比栈区的小;

二、Tagged Pointer

(1)Tagged Pointer 专门用来存储小的对象,例如 NSNumber 和NSDate。

(2)Tagged Pointer 指针的值不再是地址了,而是真正的值。所以,实际上它不再是一个对象了,它只是一个披着对象皮的普通变量而已!所以,它的内存并不存储在堆中,也不需要malloc和free。

(3)在内存读取速度快。

三、isa_t

四、散列表的原理

五、引用计数的存储

六、weak实现原理

1、弱引用对象,底层也是使用了哈希存储,或者叫散列存储,那么是对象的内存地址作为key,指向该对象的所有弱引用的指针作为值

2、释放时,就是以对象的内存地址作为key,去存储弱引用对象的哈希表里,找到所有的弱引用对象,然后设置为nil,最后移除这个弱引用的散列表

原文地址:https://www.cnblogs.com/wangchan/p/9688010.html