ios 底层

iOS虚拟内存与内存分页

2021-04-25  本文已影响0人  conowen

虚拟内存

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

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 的方式来进行访问,这时候只会创建对应的虚拟内存空间,加载需要的部分的时候才会load到物理内存中,这样就可以避免由于该文件过大,使用标准文件IO对物理内存的过度占用的问题。

Instruments Allocations

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

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


image.png

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

总结

虚拟内存是对内存的一个抽象。支持虚拟内存的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

上一篇下一篇

猜你喜欢

热点阅读