1GB大页必须通过内核启动参数default_hugepagesz=1G hugepagesz=1G hugepages=N静态预分配,运行时无法通过/proc/sys/vm/nr_hugepages_1GB动态创建;需确认CPU支持pdpe1gb、内核启用CONFIG_HUGETLB_PAGE_SIZE_1GB,且NUMA节点内存充足。

必须用 default_hugepagesz=1G hugepagesz=1G hugepages=N 写死在内核启动参数里,运行时无法通过 /proc/sys/vm/nr_hugepages_1GB 动态创建 —— 这是 1GB 大页最常踩的坑。
确认 CPU 和内核是否真支持 1GB 大页
不是所有 x86_64 机器都能用 1GB 页。缺任一条件都会导致 hugepages= 参数被忽略、cat /proc/meminfo | grep HugePages_Total 显示为 0:
- 执行
grep pdpe1gb /proc/cpuinfo:有输出才表示 CPU 支持(Intel E5-26xx v3+ / AMD EPYC 7001+) - 检查内核配置:
grep CONFIG_HUGETLB_PAGE_SIZE_1GB=y /boot/config-$(uname -r) - 确认当前页大小:
getconf PAGESIZE应为4096(不影响 1GB 页,但能验证基础环境)
静态预分配 1GB 大页(唯一可靠方式)
1GB 大页必须在系统启动早期锁定连续物理内存,运行时无法动态分配(/proc/sys/vm/nr_hugepages_1GB 在多数内核版本中根本不存在或只读)。操作步骤严格按顺序:
- 计算页数:例如要给虚拟机预留 8GB,则
8 * 1024 / 1 = 8192页(注意单位是 GB,不是字节) - 编辑
/etc/default/grub,在GRUB_CMDLINE_LINUX行末尾追加:default_hugepagesz=1G hugepagesz=1G hugepages=8192 - 执行
sudo update-grub && sudo reboot;重启后立即验证:cat /proc/meminfo | grep -i "hugepage.*1g\|hugepages_total",应看到HugePages_Total: 8192且Hugepagesize:显示1048576 kB
让 KVM 虚拟机真正用上 1GB 大页
仅预分配不够,libvirt 默认仍走 2MB 或普通页。需显式绑定并禁用干扰项:
- 关闭透明大页(THP):
echo never > /sys/kernel/mm/transparent_hugepage/enabled(否则 KVM 可能 fallback 到 THP,失去确定性) - 在虚拟机 XML 配置中启用
<memorybacking></memorybacking>段:<memorybacking><hugepages></hugepages><locked></locked></memorybacking>
并确保<memory></memory>值 ≤ 预分配总量(如 8388608 KiB) - 验证是否生效:启动虚拟机后,在宿主机执行
grep -i huge /proc/$(pidof qemu-system-x86_64)/smaps | head -3,应看到非零的AnonHugePages:值;同时cat /proc/meminfo | grep HugePages_Free应明显减少
为什么不能只靠 nr_hugepages_1GB?
该 sysctl 接口在主流发行版(RHEL 8/9、Ubuntu 22.04+、OpenEuler 22.03)的默认内核中未启用或不可写。即使内核编译了 CONFIG_HUGETLB_PAGE_SIZE_1GB,也需额外补丁或自定义内核才能暴露该接口。生产环境切勿依赖它 —— 所有稳定方案都基于 GRUB 参数静态分配。另外,1GB 页对 NUMA 敏感,若虚拟机绑定了特定 node(如 numactl --membind=0),而 1GB 页只在 node 1 上成功分配,KVM 启动会直接 OOM。











