[iOS] 内存五大区

2021-01-19  本文已影响0人  沉江小鱼

1. 介绍

iOS中,内存主要分为栈区堆区全局区常量区代码区五大区域,如下图所示:

image.png

2. 栈区

2.1 介绍
2.2 存储的数据

栈区的内存是由编译器自动分配并释放的,主要用来存储:

3. 堆区

3.1 介绍
3.2 存储的数据

堆区主要由开发者动态分配和释放,如果开发者不释放,程序结束后,则由操作系统回收

注意:当需要访问堆中内存时,一般需要先通过对象读取到栈区的指针地址,然后通过指针地址访问堆区

4. 全局区 (静态区,.bss & .data)

其中,全局变量是指变量值可以在运行时被动态修改,而静态变量是static修饰的变量,包含静态局部变量和静态全局变量。

5. 常量区 (.rodata)

常量区是编译时分配的内存空间,在程序结束后由系统释放,主要存放已经使用了的,且没有指向的字符串常量。
字符串常量可能会在程序中多次使用,所以在程序运行之间就会提前分配内存。

6. 代码区(.text)

代码区是编译时分配主要用于存放程序运行时的代码,代码会被编译成二进制存进内存的。

7. 验证

举个例子,看看下面的代码,变量在内存中是如何分配的:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    NSInteger i = 123;
    NSLog(@"i的内存地址:%p", &i);
    
    NSString *string = @"CJL";
    NSLog(@"string的内存地址:%p", string);
    NSLog(@"&string的内存地址:%p", &string);
    
    NSObject *obj = [[NSObject alloc] init];
    NSLog(@"obj的内存地址:%p", obj);
    NSLog(@"&obj的内存地址:%p", &obj);
}

输出结果如下:

2021-01-19 20:38:48.645299+0800 KVC[42501:2211601] i的内存地址:0x7ffee4107138
2021-01-19 20:38:48.645439+0800 KVC[42501:2211601] string的内存地址:0x10baf9040
2021-01-19 20:38:48.645553+0800 KVC[42501:2211601] &string的内存地址:0x7ffee4107130
2021-01-19 20:38:48.645663+0800 KVC[42501:2211601] obj的内存地址:0x600001ba8110
2021-01-19 20:38:48.645761+0800 KVC[42501:2211601] &obj的内存地址:0x7ffee4107128

8. 函数栈&栈帧

如下图所示,是经典图 - ARM的栈帧布局方式:

image.png

注意:一般情况下是不需要考虑堆栈的带下,但是事实上它们都是有限制的,过多的递归会导致栈溢出,过多的alloc对象会导致堆溢出。

推荐 阮一峰-汇编语言入门教程

上一篇 下一篇

猜你喜欢

热点阅读