iOS Memory 内存详解

0. 前言

本文以 iOS Memory 的相关内容作为主题,主要从一般操作系统的内存管理、iOS 系统内存、app 内存管理等三个层面进行了介绍,主要内容的目录如下:

iOS 是基于 BSD 发展而来,所以先理解一般的桌面操作系统的内存机制是非常有必要的。在此基础之上,本文会进一步在 iOS 系统层面进行分析,包括 iOS 整体的内存机制,以及 iOS 系统运行时的内存占用的情况。最后会将粒度缩小到 iOS 中的单个 app,讲到单个 app 的内存管理策略。

1. 操作系统的内存机制

为了从根本上更好地理解和分析 iOS 系统上的内存特性,我们首先需要正确理解一般操作系统通用的内存机制。

冯·诺依曼结构

冯·诺依曼结构(Von Neumann architecture)在 1945 年就已经被提出了, 这个概念当时十分新颖,它第一次将存储器和运算器分离,导致了以存储器为核心的现代计算机的诞生。

在冯·诺依曼结构中,存储器有着重要地位,它存放着程序的指令以及数据,在程序运行时,根据需要提供给 CPU 使用。可以想象,一个理想的存储器,应该是兼顾读写速度快、容量大、价格便宜等特点的,但是鱼和熊掌不可兼得,读写速度越快的存储器也更贵、容量更小。

但冯·诺依曼结构存在一个难以克服的问题,被称为冯·诺依曼瓶颈 —— 在目前的科技水平之下,CPU 与存储器之间的读写速率远远小于 CPU 的工作效率。简单来说就是 CPU 太快了,存储器读写速度不够快,造成了 CPU 性能的浪费。

既然现在我们没办法获得完美的存储器,那我们如何尽量突破冯·诺依曼结构的瓶颈呢?现行的解决方式就是采用多级存储,来平衡存储器的读写速率、容量、价格。

存储器的层次结构

存储器主要分为两类:易失性存储器速度更快,断电之后数据会丢失;非易失性存储器容量更大、价格更低,断电也不会丢失数据。随机访问存储器 RAM 也分为两类,其中 SRAM 速度更快,所以用作高速缓存,DRAM 用作主存。只读存储器 ROM 实际上只有最开始的时候是只读的,后来随着发展也能够进行读写了,只是沿用了之前的名字。

上图就是多层存储器的具体情况,我们平时常说的内存,实际上就是指的 L4 主存。而 L1-L3 高速缓存和主存相比,速度更快,并且它们都已经集成在 CPU 芯片内部了。其中 L0 寄存器本身就是 CPU 的组成部分之一,读写速度最快,操作耗费 0 个时钟周期。

简单来说,存储器的分级实际上就是一种缓存思想。金字塔底部的部分容量大,更便宜,主要是为了发挥其存储属性;而金字塔尖的高速缓存部分读写速度快,负责将高频使用的部分缓存起来,一定程度上优化整体的读写效率。

为什么采用缓存就能够提高效率呢?逻辑上理解起来其实很简单,具体来说就是因为存在局部性原理(Principle of locality) —— 被使用过的存储器内容在未来可能会被多次使用,以及它附近的内容也大概率被使用。当我们把这些内容放在高速缓存中,那么就可以在部分情况下节约访问存储器的时间。

CPU 寻址方式

那么,CPU 是如何访问内存的呢?内存可以被看作一个数组,数组元素是一个字节大小的空间,而数组索引则是所谓的物理地址(Physical Address)。最简单最直接的方式,就是 CPU 直接通过物理地址去访问对应的内存,这样也被叫做物理寻址。

物理寻址后来也扩展支持了分段机制,通过在 CPU 中增加段寄存器,将物理地址变成了 "段地址":"段内偏移量" 的形式,增加了物理寻址的寻址范围。

不过支持了分段机制的物理寻址,仍然有一些问题,最严重的问题之一就是地址空间缺乏保护。简单来说,因为直接暴露的是物理地址,所以进程可以访问到任何物理地址,用户进程想干嘛就干嘛,这是非常危险的。

现代处理器使用的是虚拟寻址的方式,CPU 通过访问虚拟地址(Virtual Address),经过翻译获得物理地址,才能访问内存。这个翻译过程由 CPU 中的内存管理单元(Memory Management Unit,缩写为 MMU)完成。

具体流程如上图所示:首先会在 TLB(Translation Lookaside Buffer)中进行查询,它表位于 CPU 内部,查询速度最快;如果没有命中,那么接下来会在页表(Page Table)中进行查询,页表位于物理内存中,所以查询速度较慢;最后如果发现目标页并不在物理内存中,称为缺页,此时会去磁盘中找。当然,如果页表中还找不到,那就是出错了。

翻译过程实际上和前文讲到的存储器分级类似,都体现了缓存思想:TLB 的速度最快,但是容量也最小,之后是页表,最慢的是硬盘。

虚拟内存

刚才提到,直接使用物理寻址,会有地址空间缺乏保护的严重问题。那么如何解决呢?实际上在使用了虚拟寻址之后,由于每次都会进行一个翻译过程,所以可以在翻译中增加一些额外的权限判定,对地址空间进行保护。所以,对于每个进程来说,操作系统可以为其提供一个独立的、私有的、连续的地址空间,这就是所谓的虚拟内存。

虚拟内存最大的意义就是保护了进程的地址空间,使得进程之间不能够越权进行互相地干扰。对于每个进程来说,操作系统通过虚拟内存进行"欺骗",进程只能够操作被分配的虚拟内存的部分。与此同时,进程可见的虚拟内存是一个连续的地址空间,这样也方便了程序员对内存进行管理。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值