先说内存存储区域分类:

代码区(text segment):主要包含操作代码和操作对象的地址,地址指向对象存放的区域(堆,栈,静态存储区等),具体的数值也包含在代码中。代码区的代码按照程序规则顺序执行,反复,则需要使用跳转指令,递归,需要借助栈来实现。

静态存储区(data segment):主要存储全局变量(extern),静态变量(static),主要特点是指初始化一次

未初始化数据区(bss):主要存储全局未初始化的变量,例如未在任何方法中声明的一些变量:NSString *age;

栈(stack):由编译器自动分配和释放,栈的栈顶地址和容量大小时系统预先规定好的,所以是一块连续的内存区域。存储非静态的局部变量,函数方法参数和返回值的指针等,栈的大小一般只有几兆,当系统内存不够分配时,系统会提示栈内存溢出。递归,每次地柜调用方法时,都会生成一个新的栈列,这样多个调用方法之间的变量不会混淆。

 

堆区(heap): 位于bss和栈之间,由程序员动态分配,需要手动释放,或者程序结束时,os自动释放

 

内存的分配方式:

静态分配:编译器在处理程序源代码时分配,在程序执行之前进行,效率比较高,静态对象是有名字的变量,可以直接对其进行操作,自动分配,自动释放

动态分配:程序在执行时,调用malloc库函数申请内存,动态对象时没有名字的变量,通过指针进行间接操作,手动释放

 

堆和栈的区别:

1.储存对象不同

2.管理方式不同:栈自动分配释放,堆手动分配释放

3.空间大小不同:栈大小一般只有1到2m,且是一段连续的区域,栈中的元素都是有序的,先进后出的原则,不会出现从中间弹出的情况。堆是从高地址扩展的数据结构,不连续,系统用链表来存储地址,堆的空间比较大,手动分配和释放,比较灵活

4.是否出现泄漏:栈自动分配和释放,不会出现泄漏。堆上手动分配空间,且分配的空间的不连续,会出现大量的碎片,使用效率并不高,需要手动释放,防止出现泄漏

5.增长方向不同:堆的内存地址增长从低到高,栈相反

6.分配方式不同:栈自动分配释放,堆手动分配释放

7.分配效率不同:栈由系统分配,入栈出栈都有专门的指令,效率较高。堆需要计算内存空间大小,不够分配的,需要重新整理内存空间,所以效率较低