VirtualBox是否分配操作系统专用huge pages?大内存VM性能疑问
我在使用VirtualBox运行大内存虚拟机时碰到了严重的性能问题——连续运行几天后,CPU密集型任务会变得异常缓慢。经过反复测试,我发现这个问题和虚拟机分配的内存量直接挂钩:
- 分配48GB内存时,性能衰减问题必现
- 仅分配6GB内存,或者开启虚拟机的
largepages设置时,完全不会出现性能异常
这个发现挺有意思的,因为largepages在Linux系统里默认是关闭的,官方文档也只提到开启它能带来约5%的性能提升,完全没说在大内存场景下它是保障性能的必要条件。而且更坑的是,有些情况下VirtualBox会直接忽略largepages设置,比如日志里会出现这样的提示:
00:00:42.866663 PGMR3PhysAllocateLargePage: allocating large pages takes too long (last attempt 103 ms; nr of timeouts 11); DISABLE
为了搞清楚背后的原因,我深入研究了largepages对VirtualBox内存管理的实际影响,最后得出一个结论:VirtualBox的largepages其实是自己实现了一套类似操作系统“huge pages”的机制,但它并没有直接使用系统的huge pages——既不是透明大页(transparent)也不是hugetlb*类型的,而是从系统申请普通的4KB页面,然后在内部把它们组合成2MB的块,当作单个逻辑页来使用。
回到我的性能问题上,这就意味着内存管理的性能差异完全来自VirtualBox内部,和宿主机系统的优化无关。不过反过来想,如果VirtualBox真的是自己实现了类huge pages机制,那就能解释为什么开启--largepages能带来这么明显的性能提升——就像其他用madvise之类的方式使用系统huge pages的软件一样。如果--largepages的影响真的像我遇到的这么大,甚至可以说VirtualBox存在一个bug:它没有针对大内存虚拟机强制启用这个设置。
所以我现在想确认一下我的假设是不是正确的——VirtualBox的largepages机制真的只使用系统的普通4KB页面,而不是直接调用系统的专用huge pages吗?
相关代码片段
VBox/VMM/VMMR0/PGMR0.cpp
248 int rc = GMMR0AllocateLargePage(pGVM, pVM, idCpu, _2M, 249 &pVM->pgm.s.aLargeHandyPage[0].idPage, 250 &pVM->pgm.s.aLargeHandyPage[0].HCPhysGCPhys);
VBox/VMM/VMMR0/GMMR0.cpp
3081 RTR0MEMOBJ hMemObj; 3082 rc = RTR0MemObjAllocPhysEx(&hMemObj, GMM_CHUNK_SIZE, NIL_RTHCPHYS, GMM_CHUNK_SIZE); 3083 if (RT_SUCCESS(rc))
VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c
323 # ifdef VBOX_USE_INSERT_PAGE 324 paPages = alloc_pages(fFlagsLnx | __GFP_COMP | __GFP_NOWARN, rtR0MemObjLinuxOrder(cPages)); 325 # else 326 paPages = alloc_pages(fFlagsLnx | __GFP_NOWARN, rtR0MemObjLinuxOrder(cPages)); 327 # endif
内容的提问来源于stack exchange,提问作者Thorsten Schöning

