说说内存虚拟化那些年走过的弯路和尝试,算是个探索历程吧
- 问答
- 2026-01-07 11:25:24
- 2
说起内存虚拟化,这条路可不是一开始就顺风顺水的,最早的时候,人们想法很简单,就是想让一台物理电脑能同时跑好几个操作系统,CPU的指令还好说,可以靠软件模拟或者后来硬件帮忙截获,但内存管理这块,真是块硬骨头。
最开始流行的方法叫“影子页表”,这名字听起来有点神秘,其实原理挺直白的,你想啊,每个虚拟机里的操作系统(叫Guest OS)都觉得自己独占了整个内存,它有自己的“虚拟地址”到“物理地址”的映射表,这就是它的页表,但事实上,物理内存只有一块,是所有虚拟机共享的,那怎么办?虚拟化软件(VMM或Hypervisor)就偷偷为每个虚拟机再维护一套“影子页表”,这套影子页表是直接映射到真实机器硬件的物理地址的。
这个过程有点像“中间商”赚差价,但非常辛苦,Guest OS每次修改自己的页表,VMM都得盯着,截获这个修改操作,然后根据Guest OS想改的内容,结合自己管理的真实物理内存情况,去更新那份“影子页表”,让CPU的内存管理单元(MMU)直接使用这套影子页表来做地址转换,这样做的好处是,最终地址转换是硬件直接完成的,速度很快,但坏处太明显了,VMM太累了!它要维护一大堆影子页表,每次Guest OS的页表有变动,它都得跟着忙活,开销非常大,而且非常复杂,容易出问题,这算是早期一个很主流的弯路,大家发现虽然性能最终还行,但管理成本太高了。
这时候,有大佬就想,能不能让Guest OS自己管自己的内存映射,别老让VMM在中间当这个“翻译官”了?“软件方式的页表虚拟化”思路被提了出来,主要代表就是“x86平台上的内存虚拟化”相关论文里描述的方法,这个思路的核心是,VMM不再维护那个复杂的影子页表了,而是选择“相信”Guest OS,它让Guest OS自由地管理它认为的“物理内存”(我们称之为“客户物理地址”),但当Guest OS想要告诉CPU“把这个虚拟地址映射到那个物理地址”时,VMM会介入,它不直接阻止,而是把Guest OS想映射的“客户物理地址”再翻译一层,转换成真正的“机器物理地址”。

简单说,就是做了两次地址转换:第一次,Guest OS把“虚拟地址”映射到它以为的“物理地址”;第二次,VMM再把这个“假物理地址”映射到真实的“机器物理地址”,听起来好像更绕了?确实是,这个方法虽然减轻了VMM维护影子页表的负担,但地址转换的过程完全由软件来模拟,速度慢得让人无法接受,这可以说是另一个方向的尝试,但实践证明,纯软件来做两次映射,性能是硬伤,这条路也没能成为主流。
软件的路子走起来磕磕绊绊,大家终于意识到,光靠软件耍小聪明,可能解决不了根本问题,得需要硬件来帮一把,这就催生了硬件辅助虚拟化技术,在内存方面,就是AMD的NPT和Intel的EPT技术,这个思路可以说是“拨云见日”,它直接在CPU的硬件层面增加了第二层地址转换的功能。
以前CPU的MMU只负责一次转换(虚拟到物理),现在好了,硬件直接支持两次转换:Guest OS负责管理从“虚拟地址”到“客户物理地址”的映射(第一层),而VMM则负责管理从“客户物理地址”到“机器物理地址”的映射(第二层),CPU硬件会自动、透明地完成这两层转换。

这下可省大事了!Guest OS可以像在真机上一样随意修改自己的页表,VMM不用再像影子页表那样劳心劳力地实时同步,也无需像纯软件方式那样笨拙地模拟,硬件接管了最耗性能的地址转换工作,效率极高,这可以说是内存虚拟化路上一个里程碑式的成功,终于找到了一条既高效又简洁的道路。
除了管理内存映射,另一个棘手的问题是内存不够用怎么办?物理内存就那么多,如果好几个虚拟机都要用很多内存,岂不是很快就爆掉了?于是又有了“内存超售”和“内存去重”之类的技术,内存气球”技术,这个想法很巧妙,它在每个虚拟机里安装一个特殊的驱动程序,这个驱动就像一个“气球”,当VMM发现物理内存紧张时,就通知这个“气球”驱动在虚拟机内部“吹气球”——也就是申请占用一部分该虚拟机认为可用的内存,这部分内存被“气球”占住后,Guest OS就不会再去使用了,然后VMM就可以心安理得地把这些被“隔离”出来的真实物理内存回收,分配给其他更需要的虚拟机,当原来那台虚拟机需要更多内存时,VMM就让“气球”“放气”,释放内存还给Guest OS使用,这个方法虽然需要虚拟机内部配合(要装驱动),但确实是一种行之有效的动态调整内存的软件方案。
再比如“内存去重”,也叫“内存共享”,它发现不同的虚拟机里可能运行着一样的操作系统或者一样的应用程序,它们在内存中保存的内容可能有很多是相同的,比如大家都装了一样的Windows系统,那系统内核的那部分代码在内存里肯定是一模一样的,VMM就在后台悄悄地扫描这些内存页,发现内容完全一样的,就只在物理内存里保留一份,然后让多个虚拟机都来映射这一份内存,这样就节省了大量的物理内存空间,这么做也有代价,就是扫描和比较会消耗CPU资源,属于一种用计算换空间的权衡。
所以你看,内存虚拟化这条路,就是从最初笨重复杂的“影子页表”,到性能低下的“软件二次映射”,最后在硬件辅助下找到了优雅的解决方案(EPT/NPT),为了更高效地利用宝贵的内存资源,又衍生出了“内存气球”、“内存去重”这些锦上添花的技术,整个历程就是一个不断试错、不断优化,最终软硬件结合,才达到今天这样高效、稳定状态的过程。
本文由畅苗于2026-01-07发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://www.haoid.cn/wenda/76163.html
