美文网首页iOS 笔记
iOS程序中的内存分为五个区

iOS程序中的内存分为五个区

作者: Dayon | 来源:发表于2018-05-21 18:11 被阅读2次

关于RAM&ROM

RAM与ROM就是具体的存储空间,统称为存储器。

RAM(random access memory):运行内存,CPU可以直接访问,读写速度非常快,但是不能掉电存储。它又分为:

动态DRAM,速度慢一点,需要定期的刷新(充电),我们常说的内存条就是指它,价格会稍低一点,手机中的运行内存也是指它。

静态SRAM,速度快,我们常说的一级缓存,二级缓存就是指它,当然价格高一点。

ROM(read only memory):存储性内存,可以掉电存储,例如SD卡、Flash(机械磁盘也可以简单的理解为ROM)。用的多的:NandFlash,还有NorFlash,现在用的已经比较少了(两者主要区别是前者空间大,便宜,后者可以直接运行程序,读取速度快)。

由于RAM类型不具备掉电存储能力(即一停止供电数据全没了,从新上电后全是乱码,所以需要初始化),所以app程序一般存放于ROM中。RAM的访问速度要远高于ROM,价格也要高。

RAM与ROM协同工作
由于RAM不能掉电存储,所以我们的APP程序,刷机包,下载的文件等等,都是在ROM里面存储的。

手机里面使用的ROM基本都是NandFlash,CPU是不能直接访问的,而是需要文件系统/驱动程序(嵌入式中的EMC)将其读到RAM里面,CPU才可以访问。另外,RAM的速度也比NandFlash快。

内存分区

说到内存分区,内存即指的是RAM。
内存分为五个区:栈区(系统管理的地方)、堆区(程序员控制的地方)、静态区(全局区)、常量区、代码区。

image.png

1、栈区(stack): 由编译器自动分配并释放,存放函数的参数值,局部变量等。栈是系统数据结构,对应线程/进程是唯一的。

优点:

  • 快速高效,缺点时有限制,数据不灵活。[先进后出]
  • 栈空间分静态分配 和动态分配两种。
  • 静态分配是编译器完成的,比如自动变量(auto)的分配。
  • 动态分配由alloca函数完成。
  • 栈的动态分配无需释放(是自动的),也就没有释放函数。
  • 为可移植的程序起见,栈的动态分配操作是不被鼓励的!

2、堆区(heap) :由程序员分配和释放,如果程序员不释放,程序结束时,可能会由操作系统回收 ,比如在ios 中 alloc 都是存放在堆中。

优点:

  • 灵活方便,数据适应面广泛,但是效率有一定降低。[顺序随意]
  • 堆是函数库内部数据结构,不一定唯一。
  • 不同堆分配的内存无法互相操作。
  • 堆空间的分配总是动态的
  • 虽然程序结束时所有的数据空间都会被释放回系统,但是精确的申请内存,释放内存匹配是良好程序的基本要素。

3、全局区(静态区) (static): 全局变量和静态变量的存储是放在一起的,初始化的全局变量和静态变量存放在一块区域,未初始化的全局变量和静态变量在相邻的另一块区域,程序结束后有系统释放。

注意:全局区又可分为未初始化全局区:
.bss段和初始化全局区:data段。
举例:int a;未初始化的。int a = 10;已初始化的。

例子代码:

int a = 10; 全局初始化区
char *p; 全局未初始化区

 main{
   int b; 栈区
   char s[] = "abc" 栈
   char *p1; 栈 
   char *p2 = "123456";  123456\\\\0在常量区,p2在栈上。
   static int c =0; 全局(静态)初始化区 

   w1 = (char *)malloc(10); 
   w2 = (char *)malloc(20); 
   分配得来得10和20字节的区域就在堆区。 
 }

4、文字常量区: 存放常量字符串,程序结束后由系统释放

5、程序代码区: 存放函数的二进制代码

总结:

  • 栈:由系统自动分配,速度较快,不会产生内存碎片 [先进后出]
  • 堆:是由alloc分配的内存,速度比较慢,而且容易产生内存碎片,不过用起来最方便

打个比喻来说:

  • 使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。
  • 使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。

程序运行举例(CPU RAM ROM之间协同)

首先了解下:虚拟内存与物理内存。

手机上的所有程序都是依托操作系统,运行在虚拟内存上的,每一个APP都会以为自己拥有所有的虚拟内存。比如一个手机,它是32位操作系统(一般也是32位总线),真实的物理内存为2G,那么他的寻址空间为4G(2的32次方),对于APP来说,它觉得自己拥有4G的内存,虽然这是不可能的(或者说同一时间是不可能的),但是,操作系统只要保证APP当时用到的地址空间有真实的物理地址对应就可以,APP也不需要知道那对应的2G真实物理内存具体在哪里。不要求4G的虚拟内存同一时间都有真实的物理内存相对应,当然那也是不可能的,因为只有2G物理内存。

在下面的举例中,只考虑虚拟内存

当我们点击手机屏幕APP的Icon启动一个APP(例如微信)时,操作系统会为微信开辟4G的虚拟内存空间(开辟真实的物理内存,对应一部分到4G的虚拟内存),操作系统会把存储在ROM里面微信的部分代码(受空间所限,不可能全部拷贝),拷贝到上一步开辟的4G内存空间的代码区,如上图,然后CPU就可以访问RAM来运行微信的程序了 。

假设通过微信我们下载了一个100M的视频,那么会从服务器一点一点的下载到RAM,然后再从RAM写到ROM存储。这样才能保证,我们关掉微信并再次打开时视频还在。假设隔一段时间,我们要看视频,程序会将它从ROM读到RAM然后解码播放。


CPU RAM ROM之间协同

注意

当一个app启动后,代码区,常量区,全局区地址已固定,因此指向这些区的指针不会为空而产生崩溃性的错误。而堆区和栈区是时时刻刻变化的(堆的创建销毁,栈的弹入弹出),所以当使用一个指针指向这两个区里面的内存时,一定要注意内存是否已经被释放,否则会产生程序崩溃(编程中很常见)

相关文章

  • 内存5大区

    iOS程序中的内存分配分为5大区 内存5大区:堆,栈,方法区,全局区,常量区 栈:不需要手动管理内存,会自动清理栈...

  • iOS开发最新:各大厂面试题(二)

    一、iOS程序内存分为几个区 iOS内存分为5大区域 1. 栈区:编译器自动分配并释放,存放函数的参数值,局部变量...

  • 2020 iOS 面试题集 2

    iOS程序内存分为几个区 iOS内存分为5大区域 栈区:编译器自动分配并释放,存放函数的参数值,局部变量等。栈是系...

  • JAVA变量

    内存 系统的内存可大略分为3个区域 系统区 程序区 数据区 程序执行时 程序代码会加载到内存中的程序区 数据暂时存...

  • iOS程序中的内存分为五个区

    关于RAM&ROM RAM与ROM就是具体的存储空间,统称为存储器。 RAM(random access memo...

  • iOS 内存五大区

    在 iOS 开发中,内存主要分为堆区、栈区、全局区、常量区、代码区五大区域 堆(heap)区 是有程序员分配和释放...

  • 内存布局

    一、iOS程序的内存布局 在iOS程序的内存布局中从低到高分保留区、代码段、数据段、堆区、栈区、内核区,具体存储信...

  • iOS 内存基础知识及堆区和栈区的区别

    iOS内存区域大致分为;栈区,堆区,全局区(静态区),文字常量区,程序代码区 栈区 栈区(stack)由编译器自动...

  • iOS内存相关问题小结

    1.iOS内存 IOS 内存区主要可以划分为五个区,栈区、堆区、全局变量区、常量区、代码区。 栈区:系统负责内存管...

  • iOS内存五大区

    iOS内存五大区 在iOS中,内存主要分为:栈区、堆区、全局区(静态区)、常量区以及代码区这五大区。本文将对这五大...

网友评论

    本文标题:iOS程序中的内存分为五个区

    本文链接:https://www.haomeiwen.com/subject/tgljgxtx.html