一些虚拟机管理程序使用一种称为“膨胀”的方法(至少是KVM所谓的“膨胀”)来优化内存使用,该方法对VM之间的内存进行重复数据删除,并将普通页面设置为只读,并在写入时进行复制。
这与fork调用相反。
在操作系统级别上实现流程是否可行(我主要想到的是在同一站点上使用带有多个选项卡的Chromium浏览时重复存储),是否已经实现?
一些虚拟机管理程序使用一种称为“膨胀”的方法(至少是KVM所谓的“膨胀”)来优化内存使用,该方法对VM之间的内存进行重复数据删除,并将普通页面设置为只读,并在写入时进行复制。
这与fork调用相反。
在操作系统级别上实现流程是否可行(我主要想到的是在同一站点上使用带有多个选项卡的Chromium浏览时重复存储),是否已经实现?
Answers:
实际上,您所描述的内容使膨胀和“同一页面合并”混淆了。我将尝试详细说明两者,以使区别显而易见。
内存膨胀
这是一个技巧,可确保分配给来宾虚拟机的某些内存仍可被另一个来宾或主机本身(缓存等)使用。可以通过以下方式完成:
来宾内核注入了一个驱动程序,该驱动程序监视来宾内存使用情况,并“窃取”一些未使用的内存(将其分配给来宾内存空间,以确保该来宾服务器上的任何内容都无法触及该范围)。
然后,它通知主机内核,实际上它可以从内核中删除这些内存页面,它们将不会在guest虚拟机中使用(直到guest虚拟机遇到一定的内存压力,此时气球将收缩并使用这些范围再次)。
最终,内核可以将完全相同的内存分配给另一个来宾,如果来宾使用大量可用内存运行,则可以使整个内存使用效率更高。
同一页合并
这项技术可以识别相同的内存页面,由于某种原因,它们尚未被写时复制标记为“准只读”,并对其进行了标记。
现在,在OS级别上,对这些技巧的需求有限。简而言之,在大多数情况下,当您具有相同的内存页时,它们已经是只读的(有时甚至没有CoW),因为它们大多是应用程序代码,库等。它们是通过内存映射本机打开的,因此内核可以保持它们只有一个副本在核心中(如果有的话,它也可以完全将其分页出来,并允许根据需要从主存储分页)。
在虚拟OS级别上,每个来宾子系统内正确应用了相同的原理。但是,主机内核不知道两个来宾系统是否大多数都在运行相同的代码,从而共享相同的内存-来宾系统无法进行通信来协调。
这就是为什么它有时会扫描整个系统完全相同的内存页-大部分的时间,他们将是相同的跨客户操作系统的,不是每一个内-客户内核做一个体面的工作,使记忆它的范围内整齐。因此,在一个主机内核处理50个以上来宾的典型VM环境中,可以节省大量内存。
两者都一次
膨胀和同一页合并可以很好地共存,从而为相同系统实现了相当大的内存过量使用。
要回答您的问题-有时可以在操作系统级别启用“同页面合并”。它与被解释的页面共享有关,因此最终可能是相同的,而没有相同的后备文件。
在您的Chromium示例中-进程二进制文件本身已经通过只读启动映射进行了重复数据删除-它们共享完全相同的内存空间。由于管理磁盘缓存的方式,页面缓存(选项卡的内容)通常也在进程之间共享(只读复制时复制)-可以在虚拟机中的不同进程之间模拟地打开同一磁盘文件-最佳感觉。
在不同Javascript引擎的共享状态下,优势最为明显-但我不确定它们是否分配在完全相同的内存布局中,以确保整个内存页面都是相同的。
在移动系统上这是不同的。例如,Android广泛采用KSM对不同应用程序之间的相同代码进行重复数据删除。
无论哪种情况,都可以在Linux上自己启用它(内核SamePage合并)。驱动程序导出各种统计信息,在阅读此答案之后,您应该能够进行解释,并自行决定是否适合您的目的。