暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

虚拟化技术 - 内存虚拟化(二)

术道经纬 2019-08-11
209


虚拟机内存回收

一个guest VM在创建的时候就获得了VMM/hypervisor分配给它的一定大小的物理内存。假设一个系统总共有4GB的内存,现在已经创建了3个guest VM,每个VM占有的内存都是1GB。因为VMM自身还要使用一定的内存,假设是256MB吧,那么现在系统可供分配的内存就只有756MB了。如果这时VMM收到了创建一个新的guest VM的请求,申请的内存也是1GB,超过了剩余的内存大小。地主家(VMM)也没有余粮了,怎么办呢?看来只能去各个guest VM里“抠”点内存出来了。

分给guest VM的内存还想拿回来,可没那么容易,但是VMM采用了一种很巧妙的方法,还是将一部分内存偷了回来。作为VMM,它自然是知道总有一天可能会出现内存不够分的情况,所以它早早地布好了局。它向每个被它创建的VM里都安插了一个卧底,这个卧底是作为一个伪设备的driver或者一个内核service存在于guest VM中的,它不提供被OS或上层应用程序调用的接口,而是只为VMM提供了私有的接口,只和VMM交互。

当VMM需要从guest VM回收内存时,就通知这个卧底:你可以行动了。于是这个卧底就开始向guest OS申请内存,但它不会真正使用这些申请到的内存,而是通知VMM:老大,这些内存可以被回收了。作为卧底,自然是要能屈能伸,它就像一个气球一样,通过自己在guest VM中的膨胀(inflation),为VMM实现了“圈地”的功能。这些圈来的地名义上还是guest VM的,但实际上已经被VMM控制了,VMM完全可以把这些回收的内存挪作他用。

气球的膨胀势必导致guest VM所拥有的物理内存资源减少,如果接下来guest VM运行过程中出现了内存紧缺的情况,那么它将启动自身的内存回收算法(参考这篇文章),这个气球里的内存自然也是回收的对象。可气球里的内存不是已经被VMM挪作他用了么?就像操作系统可以欺骗进程,让进程以为自己拥有整个内存地址空间一样(参考这篇文章),VMM也可以欺骗虚拟机。

进程使用的page frame可能会在OS启动内存回收时被page out,之后当进程再次访问这个page frame时,会触发page fault,OS此时再通过page in机制换回页面,并更改PTE中VA->PA的映射。对于进程来说,它使用的VA没有变化,因此整个过程对它的运行不会造成太大的影响,顶多就是点page in造成的延迟嘛。

类似地,guest VM如果访问了之前被VMM挪走的内存页面,依然会触发page fault,这个page fault会被VMM截获。因为反正guest VM用的都是GPA而不是真实的物理地址(参考上文),VMM归还的物理内存并不需要是之前从这个guest VM“偷”走的那部分,它只要按照同样的方法,从其他的guest VM那里回收点内存,放到内存紧缺的这个guest VM的气球里,并让气球收缩以释放内存(deflation),之后再重新建立GPA->HPA的映射就可以了。虽然物理页面被VMM替换了,但对于guest VM来说,它的GPA没有变,所以它根本感觉不到。

从VMM的角度,它之前不过是从guest VM那里“借”了点内存,因为最后毕竟还是还了的嘛,只不过是没跟guest VM打招呼罢了。这么辛(坑)苦(蒙)折(拐)腾(骗),不也是为了让有限的物理内存资源在各个guest VM之间得到充分合理的利用么。


参考:

《系统虚拟化 - 原理与实现》


文章转载自术道经纬,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论