iOS虚拟内存与内存分页

虚拟内存

虚拟内存是计算机系统内存管理的一种技术,虚拟内存为每个进程提供了一个连续、私有的地址空间,它每个进程会认为自己在使用一块大的连续的内存。事实上,每个进程的内存散布在物理内存的不同区域。或者可能被调出到备份存储中(一般在硬盘)。当一个进程请求自己的内存,操作系统负责把程序生成的虚拟地址,映射到实际存储的物理内存上。操作系统在分页表中存储虚拟地址到物理地址的映射。

OS X和iOS操作系统都默认支持虚拟内存。每个进程都拥有相同的虚拟内存空间,32位进程拥有4 GB的可寻址空间。此外,OS X为64位进程提供了大约18艾字节的可寻址空间。只有开始使用申请到的虚拟内存时,系统才会将虚拟地址映射到物理地址上,从而让程序使用真实的物理内存。

上述可以了解到虚拟内存的寻址空间是比物理内存还要大的。操作系统还会在内存不够的情况下,将某一进程的内存全部放入硬盘空间中,并在切换到该进程时再从硬盘读取出来。

虚拟内存优势

  • 为每个进程定义了一个连续的虚拟地址空间,用来映射在物理内存上不连续的内存区域;

  • 每个进程可以使用获得大于可用物理内存的内存缓冲区。当物理内存的供应量变小时,内存管理器会将物理内存页保存到硬盘中。

  • 不同进程使用的虚拟地址彼此隔离。一个进程中的代码无法更改正在由另一进程或操作系统使用的物理内存。

寻址

现代处理器使用的是一种称为 虚拟寻址(Virtual Addressing) 的寻址方式。使用虚拟寻址,CPU需要将虚拟地址翻译成物理地址,这样才能访问到真实的物理内存。 实际上完成虚拟地址转换为物理地址转换的硬件是 CPU 中含有一个被称为 内存管理单元(Memory Management Unit, MMU)的硬件。MMU 需要借助存放在内存中的页表来动态翻译虚拟地址,该页表由操作系统管理。

内存分页

虚拟内存管理器对虚拟内存地址,划分为大小统一的内存块,称为 内存页,处理器及其内存管理单元(MMU)维护一个页表,此页表是程序的逻辑地址对计算机RAM中的物理地址的映射。当程序代码访问内存中的地址时,MMU使用页表将指定的逻辑地址转换为实际的硬件内存地址。

系统将内存页分为三种状态。

活跃内存页(active pages)- 这种内存页已经被映射到物理内存中,而且近期被访问过,处于活跃状态。
非活跃内存页(inactive pages)- 这种内存页已经被映射到物理内存中,但是近期没有被访问过。
可用的内存页(free pages)- 没有关联到虚拟内存页的物理内存页集合。
当可用的内存页降低到一定的阀值时,系统就会采取低内存应对措施,在OSX中,系统会将非活跃内存页交换到硬盘上,而在iOS中,则会触发Memory Warning,如果你的App没有处理低内存警告并且还在后台占用太多内存,则有可能被杀掉。

VM Region

一个 VM Region 是指一段连续的内存页(在虚拟地址空间里),这些页拥有相同的属性(如读写权限、是否是 wired,也就是是否能被 page out)。举几个例子:
mapped file,即映射到磁盘的一个文件
__TEXT,r-x,多数为二进制
_DATA,rw-,为可读写数据
MALLOC
(SIZE),顾名思义是 malloc 申请的内存

VM Object

每个 VM Region 对应一个数据结构,名为 VM Object。Object 会记录这个 Region 内存的属性

Page fault

页缺失指的是当软件试图访问已映射在虚拟地址空间中,但是目前并未被加载在物理内存中的一个分页时,由内存管理单元MMU所发出的中断。实际上, 这并不是什么"错误"。 一个程序进程可能占几Mb内存, 但并不是所有的指令都要同时运行,所以系统不会把所有的指令都从磁盘加载到page内存,那么当cpu在执行指令时, 如果发现下一条要执行的指令不在实际的物理内存page中时, CPU 就会 生成一个 page fault, 通知MMU把下面要执行的指令从磁盘加载到物理内存page中。

把磁盘中的数据写到内存的过程是Page in
把内存中的数据写到磁盘的过程是Page out。

mmap

mmap()是在 <sys/mman.h> 中定义的一个函数,此函数的作用将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。实现这样的映射关系后,进程就可以采用指针的方式读写操作这一段内存,而系统会自动回写脏页面到对应的文件磁盘上,即完成了对文件的操作而不必再调用read,write等系统调用函数。相反,内核空间对这段区域的修改也直接反映用户空间,从而可以实现不同进程间的文件共享。

通过上面 mmap 与 文件标准IO 的对比

优势:

  • 物理内存占用延后:数据直到真正被使用时才会发生拷贝。
  • 物理内存占用减少:对于同一份文件无需在物理内存中存放两份,且文件区被划分成片,缺页异常时只将所需的页拷贝到物理内存。
  • 方便实现跨进程数据交互、共享:当映射到虚拟内存的对象被设置为共享对象,则不同进程对映射对象的写操作相互可见。

劣势:

  • 无法映射变长文件:调用mmap()时需指定要映射的文件位置和需要映射的大小范围。
  • 如果需要映射的文件过大,会导致过度占用虚拟内存:在调用mmap()后,虚拟内存空间就创建了,此时虽然不会占用物理内存,但依然会占用虚拟内存。此时可考虑只映射文件中自己需要的部分。

场景

当我们需要访问一个比较大的文件,尤其是当我们只需要访问其中的一小部分数据的时候,我们可以尝试通过 mmap 的方式来进行访问,这时候只会创建对应的虚拟内存空间,加载需要的部分的时候才会load到物理内存中,这样就可以避免由于该文件过大,使用标准文件IO对物理内存的过度占用的问题。

Instruments Allocations

使用Instruments的Allocations工具可以查看当前App说使用的内存,

总的内存占用 = All Heap Allocations + All Anonymous VM


image.png
  • All Heap Allocations,几乎所有类实例,包括 UIViewController、UIView、UIImage、Foundation 和我们代码里的各种类/结构实例。一般和我们的代码直接相关。
  • All Anonymous VM,可以看到都是由”VM:”开头的


    image.png

主要包含一些系统模块的内存占用。有些部分虽然看起来离我们的业务逻辑比较远,但其实是保证我们代码正常运行不可或缺的部分,也是我们常常忽视的部分。一般包括:

  • CG raster data(光栅化数据,也就是像素数据。注意不一定是图片,一块显示缓存里也可能是文字或者其他内容。通常每像素消耗 4 个字节)
  • Image IO(图片编解码缓存)
  • Stack(每个线程都会需要500KB左右的栈空间)
  • CoreAnimation
  • SQLite
  • network
  • 等等

总结

虚拟内存是对内存的一个抽象。支持虚拟内存的CPU需要通过虚拟寻址的方式来引用内存中的数据。CPU加载一个虚拟地址,然后发送给MMU进行地址翻译,MMU借助页表来获得物理地址。

参考
https://developer.apple.com/library/archive/documentation/Performance/Conceptual/ManagingMemory/Articles/AboutMemory.html
https://juejin.cn/post/6844904058667401230
https://zhuanlan.zhihu.com/p/49829766

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342