所有进程(执行的程序)都必须占用一定数量的内存,它或是用来存放从磁盘载入的程序代码,或是存放取自用户输入的数据等等。不过进程对这些内存的管理方式因内存用途不一而不尽相同,有些内存是事先静态分配和统一回收的,而有些却是按需要动态分配和回收的。
内存分区示意图
内存分类(RAM、ROM)
RAM(random access memory)运行内存
CPU可以直接访问,读写速度非常快,但是不能掉电存储。它又分为:
- 动态DRAM,速度慢一点,需要定期的刷新(充电),我们常说的内存条就是指它,价格会稍低一点,手机中的运行内存也是指它
- 静态SRAM,速度快,我们常说的一级缓存,二级缓存就是指它,当然价格高一点。
ROM(read only memory)存储性内存
- 可以掉电存储,例如SD卡、Flash(机械磁盘也可以简单的理解为ROM)。用的多的:NandFlash,还有NorFlash,现在用的已经比较少了(两者主要区别是前者空间大,便宜,后者可以直接运行程序,读取速度快);
Tips:
- RAM的访问速度要远高于ROM,价格也要高;
- CPU只能从RAM直接读取指令;
- app程序一般存放于ROM中。启动app时,系统会把开启的app程序从ROM中转移到RAM中。
内存分区
iOS中主要是栈区(stack)、堆区(heap)、全局区/静态区(staic) 、常量区、代码区;
栈区(stack)
- 存放局部变量,先进后出,一旦出了作用域就会被销毁,函数跳转地址,现场保护等;
- 存放的局部变量(先进后出)一旦出了作用域就会被销毁;
- 大量的局部变量,深递归,函数循环调用都可能耗尽栈内存而造成程序崩溃 ;
- 栈区不需要程序员管理内存,由编译器自动分配并释放,速度快;
- 栈区的地址从高到低分配;
堆区(heap)
- 堆区需要程序员管理内存如alloc申请内存,free释放内存,一般速度比较慢,容易产生内存碎片;
- ARC原理是基于堆区,编译器在编译的时候给对象自动添加retain、release、autorelease;
- 堆区的地址是从低到高分配;
全局区/静态区(staic)
- 包括两个部分:未初始化过和初始化过。(全局区/静态区)在内存中是放在一起的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和静态变量在相邻的另一块区域;
eg:int a;未初始化的。int a = 10;已初始化的。
常量区
- 常量字符串,还有const常量;
代码区
- 存放App代码;
tips
- 当一个app启动后,代码区,常量区,全局区大小都是已经固定的,因此指向这些区的指针不会产生崩溃性的错误,而堆区和栈区是时时刻刻变化的,所以当使用一个指针指向这个2区里面内存的时候,一定要注意内存是否已经被释放,否则会产生程序崩溃(即野指针报错)