iOS内存分区
引言
iOS的存储器包括RAM(random access memory,运行内存)和ROM(Read-Only Memory,只读存储器)。
- RAM,又称随机存储器,是与CPU直接交换数据的内部存储器,也叫主存(内存)。它可以随时读写,而且速度很快,通常作为操作系统或其他正在运行中的程序的临时数据存储媒介。
- ROM,是一种只能读出事先所存数据的固态半导体存储器。其特性是一旦储存资料就无法再将之改变或删除。通常用在不需经常变更资料的电子或电脑系统中,并且资料不会因为电源关闭而消失。
本文主要讨论iOS在程序运行中的内存分配,也就是RAM在程序运行时变量、对象等的内存分配。
内存的五大分区
- 栈区(stack):由编译器自动完成分配和释放,不需要程序员手动管理,主要存储了函数的参数和局部变量值等。栈区的地址从高到低分配
- 堆区(heap):需要程序员手动开辟并管理内存。(OC有ARC, OC对象通常不需要程序员考虑释放问题).堆区的地址是从低到高分配
- BSS段 (全局区)(静态区):包括2个部分:未初始化和初始化;
也是说,在内存中是放在一起的,比如:int a;未初始化, int a = 10 初始化的2者都在全局区/静态区。程序运行过程内存的数据一直存在,程序结束后由系统释放。 - 常量区 (数据段):专门用于存放常量,程序结束后由系统释放
- 程序代码区:用于存放程序运行时的代码,代码会被编译成二进制存进内存的程序代码区
注意事项:
1.在iOS中,堆区的内存是应用程序共享的,堆中的内存分配是系统负责的;
2.系统使用一个链表来维护所有已经分配的内存空间(系统仅仅纪录,并不管理具体的内容);
3.变量使用结束后,需要释放内存,OC中是根据引用计数==0,就说明没有任何变量使用该空间,那么系统将直接收回;
4.当一个app启动后,代码区,常量区,全局区大小已固定,因此指向这些区的指针不会产生崩溃性的错误。而堆区和栈区是时时刻刻变化的(堆的创建销毁,栈的弹入弹出),所以当使用一个指针指向这两个区里面的内存时,一定要注意内存是否已经被释放,否则会产生程序崩溃(也即是野指针报错)。