1 RAM&ROM
RAM与ROM就是具体的存储空间,统称为存储器。
RAM(random access memory):运行内存,CPU可以直接访问,读写速度非常快,但是不能掉电存储。它又分为:
动态DRAM,速度慢一点,需要定期的刷新(充电),我们常说的内存条就是指它,价格会稍低一点,手机中的运行内存也是指它。
静态SRAM,速度快,我们常说的一级缓存,二级缓存就是指它,当然价格高一点。
ROM(read only memory):存储性内存,可以掉电存储,例如SD卡。
栈区(stack)
栈区地址从高到低分配;
存放的局部变量(先进后出)一旦出了作用域就会被销毁;
大量的局部变量,深递归,函数循环调用都可能耗尽栈内存而造成程序崩溃 。
堆区(heap)
堆区的地址是从低到高分配。
ARC下OC对象runloop循环结束后(kCFRunLoopBeforeWaiting后)自动释放,CF对象需要CFRelease(CFTypeRef cf)手动释放。
全局区/静态区(static)
包括两个部分:未初始化过和初始化过。(全局区/静态区)在内存中是放在一起的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和静态变量在相邻的另一块区域;
eg:int a;未初始化的。int a = 10;已初始化的。
常量区
常量字符串就是放在这里,还有const常量;
代码区
存放App代码,4S(iOS7)只有74M;
3 RAM&ROM协调工作
4 . 注意事项
在iOS中,堆区的内存是应用程序共享的,堆中的内存分配是系统负责的;
系统使用一个链表来维护所有已经分配的内存空间(系统仅仅纪录,并不管理具体的内容);
变量使用结束后,需要释放内存,OC中是根据引用计数==0,就说明没有任何变量使用该空间,那么系统将直接收回;
当一个app启动后,代码区,常量区,全局区大小已固定,因此指向这些区的指针不会产生崩溃性的错误。而堆区和栈区是时时刻刻变化的(堆的创建销毁,栈的弹入弹出),所以当使用一个指针指向这两个区里面的内存时,一定要注意内存是否已经被释放,否则会产生程序崩溃(也即是野指针报错)。
5 . 其它操作系统
iOS是基于UNIX、Android是基于Linux的,在Linux和unix系统中,内存管理的方式基本相同;
Android应用程序的内存分配也是如此。除此以外,这些应用层的程序使用的都是虚拟内存,它们都是建立在操作系统之上的,只有开发底层驱动或板级支持包时才会接触到物理内存,
举例:在嵌入式Linux中,实际的物理地址只有64M甚至更小,但是虚拟内存却可以高达4G;
栈区 (stack [stæk]): 由编译器自动分配释放
局部变量是保存在栈区的
方法调用的实参也是保存在栈区的
堆区 (heap [hiːp]): 由程序员分配释放,若程序员不释放,会出现内存泄漏
赋值语句右侧 使用 new 方法创建的对象
被创建对象的所有 成员变量
BSS 段(也叫静态区) : 程序结束后由系统释放
教科书:未被初始化的全局变量和静态变量.
Xcode8中: 全局变量和静态变量,不管有没有被初始化,都存放在BSS段中.
数据段(也叫常量区) : 程序结束后由系统释放
教科书: 存储已经初始化的全局变量,静态变量,常量.
xcode8: 存储常量
代码段 : 程序结束后由系统释放
程序 编译链接 后的二进制可执行代码