前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >漫画解说 “内存映射”

漫画解说 “内存映射”

作者头像
用户7686797
发布2021-05-11 10:18:27
8530
发布2021-05-11 10:18:27
举报
文章被收录于专栏:Linux内核那些事Linux内核那些事

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

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

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

页表 并不是按字节来进行映射的,而是按照 内存页 为单位进行映射,一般一个 内存页 的大小为 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 位还是作为物理内存页的偏移量。

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Linux内核那些事 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 虚拟内存空间与物理内存空间
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档