主要参考如下连接
大页内存的使用:HugePages(大内存页)的原理与使用_rtoax的博客-CSDN博客_大页内存
1 物理内存
:也就是安装在计算机中的内存条,比如安装了 2GB 大小的内存条,那么物理内存地址的范围就是 0 ~ 2GB
2 虚拟内存
:虚拟的内存地址。由于 CPU 只能使用物理内存地址,所以需要将虚拟内存地址转换为物理内存地址才能被 CPU 使用,这个转换过程由 MMU(Memory Management Unit,内存管理单元)
来完成。在 32 位的操作系统中,虚拟内存空间大小为 0 ~ 4GB
3
页表
保存的是虚拟内存地址与物理内存地址的映射关系,页表保存在内存中。MMU
从 页表
中找到虚拟内存地址所映射的物理内存地址,然后把物理内存地址提交给 CPU,这个过程与 Hash 算法相似。
内存映射是以内存页作为单位的,通常情况下,一个内存页的大小为 4KB(如图1所示),所以称为 分页机制
4 内存映射:
在 64 位的 Linux 系统中(英特尔 x64 CPU),虚拟内存地址转换成物理内存地址的过程,如图
5
CPU 有个名为 CR3
的寄存器,用于保存 页全局目录
的起始物理内存地址(如图2所示)。所以,虚拟内存地址转换成物理内存地址的过程如下:
-
从
CR3
寄存器中获取页全局目录
的物理内存地址,然后以虚拟内存地址的 39 ~ 47 位作为索引,从页全局目录
中读取到页上级目录
的物理内存地址。 -
以虚拟内存地址的 30 ~ 38 位作为索引,从
页上级目录
中读取到页中间目录
的物理内存地址。 -
以虚拟内存地址的 21 ~ 29 位作为索引,从
页中间目录
中读取到页表
的物理内存地址。 -
以虚拟内存地址的 12 ~ 20 位作为索引,从
页表
中读取到物理内存页
的物理内存地址。 -
以虚拟内存地址的 0 ~ 11 位作为
物理内存页
的偏移量,得到最终的物理内存地址。
6 TLB
是一块高速缓存,TLB 缓存虚拟内存地址与其映射的物理内存地址。MMU 首先从 TLB 查找内存映射的关系,如果找到就不用回溯查找页表。否则,只能根据虚拟内存地址,去页表中查找其映射的物理内存地址。
7
使用大于 4KB 的内存页作为内存映射单位的机制叫 HugePages
,目前 Linux 常用的 HugePages 大小为 2MB 和 1GB,我们以 2MB 大小的内存页作为例子。
要映射更大的内存页,只需要增加偏移量部分,如 图
8
如 图 所示,现在把偏移量部分扩展到 21 位(页表部分被覆盖了,21 位能够表示的大小范围为 0 ~ 2MB),所以 页中间目录
直接指向映射的 物理内存页地址
。
这样,就可以减少 页表
部分的内存消耗。由于内存映射关系变少,所以 TLB 失效的情况也会减少。