这篇文章依次介绍一下iOS中内存的分配与分区。

1、RAM & ROM

  • 存储器(Memory)是计算机系统中的记忆设备,用来存放程序和数据。
  • iOS的存储器包括RAM(random access memory,运行内存)和ROM(Read-Only Memory,只读存储器)。
  • RAM:运行内存,不能掉电存储。
  • ROM:存储性内存,可以掉电存储,例如内存卡、Flash。
  • 由于 RAM 类型不具备掉电存储能力(即一掉电数据消失),所以 app 程序一般存放于 ROM 中。RAM 的访问速度要远高于 ROM,价格也要高。

2、App程序启动

  • App 程序启动,系统会把开启的那个 App 程序从 Flash 或 ROM 里面拷贝到内存(RAM),然后从内存里面执行代码。
  • 注意CPU 不能直接从内存卡里面读取指令!(需要 Flash 驱动)

3、iOS内存分区

  • iOS应用在内存(RAM)中运行,不同的类型在内存处于不同分区
  • 图中由进程箭头指向的代码段、全局数据段是在进程就绪状态时通过编译器装载进来的
  • 堆区、栈区、内存映射区域是在进程进入执行状态(即运行时)后向CPU(处理器)申请分配
  • 进程结束这些区域会随着销毁,保留区和内核区除外
  • 堆和栈是可增长的,它们的增长方向相对,堆向上增长,栈向下增长

下面解释一下每个区域:

保留段

  • 系统分配出来的一块空闲区域,用来处理紧急情况下的任务

代码段

  • 储存编译完成之后的指令代码(可执行代码的二进制文件)
  • 在程序编译时存入,程序结束后由系统释放
  • 通常代码段是可共享的,这使得需要频繁被执行的程序只需要在内存中拥有一份拷贝即可
  • 代码段也通常是只读的,这样可以防止其他程序意外地修改其指令
  • 在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等

常量区

  • 存放常量字符串
  • 常量区的内存在编译阶段完成分配,程序运行时会一直存在内存中,只有当程序结束后才会由操作系统释放
  • iOS中常量区的地址空间一般以0x1开头

全局数据段(全局区/静态区)

  • static修饰的变量成为静态变量,该变量内存放在全局数据段
  • 由程序编译时创建,已初始化的全局变量和静态变量存放在一块区域,未初始化的全局变量和静态变量存放在另一块区域,直到程序结束才释放
  • iOS中全局数据段的地址空间一般以0x1开头

未初始化数据(Block Started by Symbol)

  • 简称BSS,存放程序中未初始化的全局变量、静态变量等数据
  • int a,并未赋值的变量a就被认为是未初始化数据

已初始化数据(data segment)

  • 简称DATA,存放程序中已初始化的全局变量、静态变量等数据
  • int a = 10NSString *strS = @"123456789"

堆区(heap)

  • 堆一般用来存储引用类型的对象数据
  • 堆从低地址向高地址扩展数据,采用链表形式管理内存段:需要分配时对链表进行遍历,找到空间大于申请的节点分配给开发者,然后在链表中删除节点。找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中
  • 变量使用结束后,需要由开发者根据引用计数来判断是否释放(ARC下由编译器自动添加释放命令),不释放可能引起内存泄露
  • 堆区的内存是应用程序共享的,堆中的内存分配是系统负责的
  • iOS中堆的地址空间一般以0x6开头,其空间总是在程序运行时动态分配
  • 堆由于是运行时开辟、且内存区域是不连续的,导致容易出现内存碎片

内存映射段

  • mmap文件映射和匿名映射:磁盘文件的数据映射到内存,通过修改内存就能修改磁盘文件
  • 该段可以理解为用来处理有关文件映射的内容

栈区(stack)

  • 存放程序临时创建的局部变量,也就是说我们函数括弧“{}” 中除了 static 定义之外的变量(static 变量存放在数据段),包括函数的参数以及隐藏参数(id self, SEL _cmd)
  • 栈从高地址向低地址扩展,是一块连续的内存区域,遵循先进后出原则,一旦出了作用域就会被销毁
  • 栈是系统数据结构,栈是在运行时开辟,其对应的线程或进程是唯一的
  • 程序员不需要管理栈区变量的内存,由编译器自动分配释放
  • iOS中栈的地址空间一般以0x7开头
  • 可用于函数调用的现场保护和现场恢复
  • 栈的内存大小有限制。根据苹果线程编程指南,iOS的主线程栈大小不超过1MB,OS X主线程栈最大8MB,子线程栈最大512KB。子线程在创建的时候可以更改栈的大小,子线程允许设置的最小栈大小为16 KB,并且栈大小必须为4 KB的倍数。主线程的栈大小无法修改。

内核区

  • 系统内核运行的区域
  • iOS的核心是XNU内核;XNU内核是一个混合内核,其核心是一个叫Mach的微内核

一般说的五大分区

  • 堆区、栈区、全局区、常量区、代码区
  • 一段代码看出变量在哪个区
int i = 10; //全局初始化
char *a; //全局未初始化
- (void)test {int b;//栈区NSString *str = @"123";//常量区static int c = 0;//全局(静态)初始化区NSObject *obj = [[NSObject alloc]init];//堆区
}

其它操作系统

  • iOS 是基于 UNIX、Android 是基于 Linux 的,在 Linux 和 unix 系统中,内存管理的方式基本相同,Android 应用程序的内存分配也是如此
  • 这些应用层的程序使用的都是虚拟内存,它们都是建立在操作系统之上的,只有开发底层驱动或板级支持包时才会接触到物理内存。在嵌入式 Linux 中,实际的物理地址只有 64M 甚至更小,但是虚拟内存却可以高达 4G

注意事项

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

iOS——内存分配与分区相关推荐

  1. iOS内存分配与五大区域

    目录: 参考的博客: iOS内存的五大区域 : 栈区(stack) 堆区(heap): 全局区(又称静态区)(static): 文字常量区: 程序代码区: Allocations模版: 虚拟内存简介: ...

  2. iOS内存分配五大区:

    iOS内存分配五大区: 栈区,堆区,静态区(全局区),常量区,代码区 动态数据区一般就是"堆栈",栈是线性结构,堆是链式结构. 本地变量在堆栈中.通过堆栈的基地址和偏移量来访问本地 ...

  3. 程序如何在RAM ROM运行,内存分配与分区

    关于RAM ROM RAM与ROM就是具体的存储空间,统称为存储器 RAM(random access memory):运行内存,CPU可以直接访问,读写速度非常快,但是不能掉电存储.它又分为: 动态 ...

  4. 【iOS开发】—— iOS内存管理

    文章目录 1. iOS内存分配区域 1.1 栈区 1.2 堆区 1.3 常量区 1.4 全局区/静态区 1.4.1 static静态变量 1.4.2 extern全局变量 1.5 代码区 2. iOS ...

  5. 【iOS】—— 内存的五大分区

    平时我们编写程序的时候可能不太在意系统的内存问题,那么我们所编写代码变量都是怎么在内存中存取的呢?内存其实分为五大分区,栈区(系统管理的地方).堆区(程序员控制的地方).常量区(全局区).静态区和代码 ...

  6. 动态分区分配存储管理方式的内存分配回收

    在动态分区分配存储管理方式的内存分配中,当有作业请求装入时,根据作业的需要内存空间的大小查询内存各个空闲区,从中找到一个大于或等于该作业大小的内存空闲区,然后按作业需求量划出一个分区装入该作业.作业执 ...

  7. 变量 内存 分配 ios iphone

    转载说明(谢谢) http://blog.csdn.net/a21064346/article/details/7785535 点击打开链接 对于 内存分配的掌握,对于一个ios程序开发来说很重要 在 ...

  8. 【Linux 内核 内存管理】分区伙伴分配器 ② ( free_area 空闲区域结构体源码 | 分配标志位 | GFP_ZONE_TABLE 标志位区域类型映射表 |分配标志位对应的内存区域类型 )

    文章目录 一.free_area 空闲区域结构体源码分析 二.分配标志位 三.GFP_ZONE_TABLE 标志位区域类型映射表 四.分配标志位对应的内存区域类型 一.free_area 空闲区域结构 ...

  9. 内存管理-动态分区分配方式模拟

    内存管理 - 动态分区分配方式模拟 操作系统第二次课程作业 - 动态分区分配方式模拟 项目需求 假设初始态下,可用内存空间为640K,并有下列请求序列,请分别用首次适应算法和最佳适应算法进行内存块的分 ...

最新文章

  1. 用「我的世界」自动生成「现实世界」:英伟达展示AI脑补新技术
  2. java使用教程——组件及事件处理——窗口(设置窗口的颜色和背景)
  3. 7 WM配置-主数据-定义拣配区(Picking Area)
  4. 直接插入排序(C语言)实现
  5. 软件工程导论团队介绍——信科吴彦组
  6. react-cnode实践笔记
  7. Cy3014学习记录 二--开发软件使用汇总
  8. SetLocale和GetLocale函数
  9. html广告网页完整代码,HTML5设计网页动态条幅广告(Banner) 已经加上完整源代码 - 伊甸一点...
  10. java使用poi导出excel 包括多个工作簿
  11. 浙里办使用RAX框架实现单点登录功能
  12. VS2013各版本序列号
  13. 笨鸟的平凡之路-记一次spark错误
  14. 用Scrapy爬取笔趣阁小说
  15. nodejs01——安装及使用、服务端及客户端、commonjs规范、fs模块的使用(文件操作及目录操作)、stream、buffer、WebServer、端口、动态资源及静态资源、头信息、请求方式
  16. suse linux乱码,轻松解决Suse中文乱码问题
  17. ChatGPT介绍世界杯历史与编写足球游戏python程序
  18. 计算机学校校歌,【2018十大最受欢迎高校校歌】_最受欢迎的十大高校校歌
  19. HTML5+CSS3选择器
  20. 数字如潮人如水:在这个时代,你是要当算法,还是当数据?

热门文章

  1. 小A的年前面试经历——实录
  2. dw网页设计期末设计一个网页_Dreamweaver网页设计模拟试题
  3. CL201课堂笔记-RCHA认证之路-OpenStack DAY TWO - AM
  4. 固定资产的日期之折旧日期研究
  5. C#中Abstract和Virtual使用详解
  6. 全球首个TD-LTE演示网今日上海正式开通,金山瑞星同日发布“云安全”产品(每日关注:20100415)...
  7. [oracle]7788
  8. Web 1.0、Web 2.0 和 Web 3.0
  9. c语言程序 电子钢琴按键,基于51单片机8按键电子琴-简易版系统设计(原理图+程序仿真+论文)...
  10. uefiboot 文件_UEFI BIOS模式下Windows系统启动过程以及引导文件修复方法