假期学习--iOS内存五大分区

iOS内存五大分区

iOS中,内存主要分为五大区域:栈区,堆区,全局区/静态区,常量区和代码区。总览图如下。

请添加图片描述

代码区是在低地址段存放,而栈区则存放在高地址段,并且各个分区之间不是连续的。

1.栈

特点

  • 栈是从高地址向低地址存储的一块连续的内存区域,特点是先进后出(FILO)
  • 栈的地址空间在在iOS里面是0X7/ 0X16开头
  • 栈区一般是在运行时分配内存,内存空间由系统管理,也就是变量在超出了自身的作用范围之后就会被释放
  • 包含函数内部定义的局部变量以及方法参数(方法的默认参数 self,cmd) 等也都是存放在栈区。

优缺点

  • 栈区的内存由系统分配和释放,不会产生内存碎片,更快更高效。
  • 栈的内存大小被系统限制或者说比较小,不灵活,iOS主线程栈的大小1MB,其他线程512KB,Mac为8M。

请添加图片描述

2.堆区

特点

  • 堆是从低地址向高地址不连续的内存区域,和链表的结构很相似(便于增删但是不便于查询),特点是先进先出FIFO
  • 堆地址是以0X6进行开头,动态的分配空间(手动分配)
  • 在堆里存放的东西需要我们手动的管理和释放,若不及时释放就会造成内存泄漏
  • 在OC里面alloc和new都会为对象开辟空间到堆上

堆和栈的区别

优缺点

  • 栈:由系统自动分配并释放,速度较快,不会产生内存碎片。优点是快速高效,缺点时有限制,数据不灵活。
  • 堆:手动分配和释放,速度比较慢,而且容易产生内存碎片,不过用起来最灵活方便。优点是灵活方便,数据适应面广泛,但是效率有一定降低。

申请后的系统如何响应?

  • 栈:在执行存储一个函数的时候会向操作系统索要资源,栈区就是函数运行时的内存,栈区中的变量由编译器负责分配和释放,内存**随着函数的运行分配,随着函数的结束而释放,由系统自动完成。**只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
  • 堆:操作系统有一个记录空闲内存地址的链表。**当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。**由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。

申请大小的限制?

  • 栈:栈是向低地址扩展的数据结构,是一块连续的内存的区域。**栈顶的地址和栈的最大容量是系统预先规定好的,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数 ) **,如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小
  • 堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大

全局/静态区

  • 该区是编译时分配的内存空间,在iOS中一般以0x1开头,在程序运行过程中,此内存中的数据一直存在,程序结束后由系统释放
  • 未初始化的全局变量和静态变量,即BSS区(.bss)。
  • 已初始化的全局变量和静态变量,即数据区(.data)。
  • 其中,全局变量是指变量值可以在运行时被动态修改,而静态变量是static修饰的变量,包含静态局部变量和静态全局变量
int clB;
static int bssB;
int initClB = 10;
static int initBssB = 11;
- (void)testStatic {
    NSLog(@"clA = %p", &clB);
    NSLog(@"bssB = %p", &bssB);
    NSLog(@"initClB = %p", &initClB);
    NSLog(@"initBssB = %p", &initBssB);
   

}

请添加图片描述

clB 和 bssB都是未初始化,在内存是连续的地址,相差为4。
initClB和 initBssB都是初始化的数据,内存地址也是连续的。

**所以全局区的内存分为两大块连续的内存,**BSS区(.bss)和 数据区(.data)

4.常量区

  • 该区是编译时分配的内存空间,在程序运行过程中,此内存中的数据一直存在,程序结束后由系统释放。
  • 存放常量:整型、字符型、浮点、字符串等。
    常量区是编译时分配的内存空间,在程序结束后由系统释放,主要存放:
    ■ 已经使用了的,且没有指向的字符串常量
    ■ 字符串常量因为可能在程序中被多次使用,所以在程序运行之前就会提前分配内存。

5.代码区

  • 该区是编译时分配的内存空间,在程序运行过程中,此内存中的数据一直存在,程序结束后由系统释放
  • 程序运行时的代码会被编译成二进制,存进内存的代码区域。

总结

  • 堆和栈的区别
  • 栈区运行时系统分配内存,堆区手动分配内存,静态区-常量区-代码区编译时分配内存
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值