美文网首页
iOS内存划分

iOS内存划分

作者: 携YOU手同行 | 来源:发表于2020-11-02 11:41 被阅读0次

一,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基本都是NandFlashCPU是不能直接访问的,而是需要文件系统/驱动程序(嵌入式中的EMC)将其读到RAM里面,CPU才可以访问。另外,RAM的速度也比NandFlash快。

二,内存划分区域

Objective-C从名字来看就可以知道这是一门超C语言,所以了解C语言的内存模型对于理解Objective-C的内存管理、性能优化有很大的帮助。C语言内存结构如下:


C语言内存结构图.png

而Objcective-C 的结构如下:


iOS内存划分图片.png

以上就是相关的iOS内存划分的五个区域,接下来让我们具体分析一下每个区域所起到的作用是什么?分别在iOS开发过程担任了什么作用。

2.1 栈区

传入函数的参数值、函数体内声明的局部变量等,由编译器自动分配释放,通常在函数执行结束后就释放了。(注意:不包括static修饰的变量,static意味该变量存放在全局/静态区)其操作方式类似数据结构中的栈,先进后出。

栈内存分配运算内置于处理器的指令集,效率很高,但是分配的内存容量有限,比如iOS中栈区的大小是2M(看网上说,也有人说1M,我也不知道具体大小,但栈区的内存肯定不会太大)。

  • 存放的局部变量、先进后出、一旦出了作用域就会被销毁;函数跳转地址,现场保护等;
  • 程序猿不需要管理栈区变量的内存
  • 栈区地址从高到低分配;

2.2堆区

堆区的内存是由代码分配和释放,用于存放进程运行中被动态分配的内存段,堆区的大小并不固定,可动态扩张或缩减。

  • 变量通过new、alloc、malloc、realloc分配的内存块就存放在堆区。
  • 堆区的内存都是动态分配的。
  • 当进程调用alloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张)。
  • 当利用realse释放内存时,被释放的内存从堆中被剔除(堆被缩减)。
  • 如果应用程序没有释放掉,操作系统会自动回收,分配方式类似于链表。
  • 因为现在iOS基本都使用ARC来管理对象,所以也不需要手动释放。
  • 一般速度比较慢,而且容易产生内存碎片,不过用起来最方便。

2.3 全局/静态区域

全局/静态区是存放全局变量和静态变量的。
已初始化的全局变量和静态变量存放在一块区域。
未初始化的全局变量和静态变量在相邻的另一块区域。
由static修饰的变量会成为静态变量,该变量的内存由全局/静态区在编译阶段完成分配,且仅分配一次。
static可以修饰局部变量也可以修饰全局变量。
全局/静态区的内存在编译阶段完成分配,程序运行时会一直存在内存中,只有当程序结束后才会由操作系统释放。

2.4 常量区

常量区是一块比较特殊的存储区,常量区里面存放的是常量,常量字符串就存放在常量区。
常量区的内存在编译阶段完成分配,程序运行时会一直存在内存中,只有当程序结束后才会由操作系统释放。

2.5 代码区

代码区是用来存放可执行文件的操作指令(存放函数的二进制代码),其实就是存放程序的所有代码。代码区需要防止在运行时被非法修改,所以只准许读取操作,而不允许写入(修改)操作——它是不可写的。

通常代码段是可共享的,这使得需要频繁被执行的程序只需要在内存中拥有一份拷贝即可。代码段也通常是只读的,这样可以防止其他程序意外地修改其指令。另外,代码段还规划了局部数据所申请的内存空间信息。 代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读, 某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。

三,总结

在编译阶段代码区、常量区、全局/静态区就已经分配完成并且大小固定,所以指向这些区的指针不会产生崩溃性的错误。
而栈区和堆区内存分配随着程序运行而变化(堆的创建销毁,栈的弹入弹出)。
在iOS中,堆区的内存是应用程序共享的,堆区的内存分配是系统负责的。

相关文章

  • iOS 面试题及答案20道61~80(四)

    iOS 面试题及答案20道61~80(三) 61:谈谈iOS内存 61.1: 内存区域划分 iOS进程内存布局从高...

  • iOS内存划分

    一,RAM和ROM的介绍 RAM与ROM就是具体的存储空间,统称为存储器。 RAM(random access m...

  • iOS内存相关问题小结

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

  • iOS内存管理

    iOS内存管理 内存区域划分 内存区域说明栈区存放局部变量,系统自动分配和释放。 特点:容量小,速度快,有序堆区存...

  • JAVA 一维数组

    数组 JVM内存划分 A:内存划分 JVM对自己的内存划分为5个区域 * a: 寄存器:内存和CUP之间 * b:...

  • 内存划分

    静态储存区 内存在程序编译的时候就已经分配好,这快内存在程序的整个运行期间都存在。它主要存在静态数据、全局数据和常...

  • iOS内存中的区域划分

    1.栈:栈区(stack)由系统自动分配和释放,存放方法(函数)的参数值,局部变量的值等。采用“先进后出”或者“后...

  • iOS系统中的几大内存区域

    iOS系统内存划分图: **1.栈区(stack)** 栈区(stack) 由编译器自动分配并释放,存放函数的参数...

  • 2018-08-22

    数组内存空间的划分、栈内存

  • iOS 内存的区域划分与使用

    代码段 存放编译后的代码 数据段(内存分配:从低地址到高地址) 字符串常量:如:NSString *str = @...

网友评论

      本文标题:iOS内存划分

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