漫画解说 “内存映射”

Linux内核那些事

共 929字,需浏览 2分钟

 ·

2021-04-29 07:27

虚拟内存空间与物理内存空间

虚拟内存地址就好比每个班的学号,而物理内存地址就好比真实的学生。因为每个学号都对应不同的学生,所以虚拟内存地址也要映射到物理内存地址。

虚拟内存与物理内存的映射关系是通过 页表 来关联的,如下图:

页表 并不是按字节来进行映射的,而是按照 内存页 为单位进行映射,一般一个 内存页 的大小为 4KB(为什么要加一般呢,这是因为除了4KB,还有其他大小的内存页,如2MB,4MB,1GB等),页表 的每一个 页表项 都保存着物理内存页的地址。

所以,4GB 的虚拟内存空间需要 1MB 大小的页表来关联(因为 4GB / 4KB = 1MB)。也就是说,0 ~ 4095 的虚拟内存地址都是使用 页表 的第一个 页表项 来映射的,而 4096 ~ 8191 的虚拟内存地址使用 页表 的第二个 页表项 来映射的,以此类推...

那么,通过什么样的算法能把 0 ~ 4095 的虚拟内存地址转换为页表的第一个页表项呢?其实很简单,只需要把虚拟内存地址的高端 20 位作为页表的索引,而把低端 12 位作为内存页中的偏移量即可,如下图:

在上图中,还看到了一个 cr3 的东西,这是 CPU 中的一个寄存器,用于保存 页表 的物理内存地址,通过这个寄存器就能找到进程的 页表 了。

现在对内存映射的原理有了比较清晰的了解了,但现在有个问题,每个进程都要 1MB 大小的页表,那不是很浪费内存吗?的确是,因为进程很多虚拟内存地址并不会用到,为了节省页表使用的内存,x86 CPU 把页表分为 2 级,如下图:

如上图所示,把原来的 页表 划分为 页目录页表,它们的大小均为 4KB。而虚拟内存地址的高 10 位作为页目录的索引,而中间 10 位作为页表的索引,低 12 位还是作为物理内存页的偏移量。

把原来的 页表 划分为两级后,进程有些不使用的虚拟内存地址就不需要进行映射,从而节省了内存的使用。








浏览 67
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报