配置linux hugepages成功的关键是三件事:nr_hugepages需提前静态申请、memlock限制必须设为unlimited、透明大页thp必须永久关闭为never,缺一不可;否则进程无法绑定大页。

直接说结论:配置 Linux HugePages 不是“配个参数就完事”,关键在三件事——nr_hugepages 要提前申请、memlock 限制必须放开、THP 必须关死。缺一不可,否则进程根本绑不上大页。
怎么确认系统支持且当前没被禁用
别跳过这步。很多问题其实卡在内核没真启用,而不是配置写错了。
-
cat /proc/meminfo | grep -i huge—— 如果输出全空,说明HUGETLB_PAGE没编译进内核或被禁用 -
grep CONFIG_HUGETLB_PAGE /boot/config-$(uname -r)—— 必须看到CONFIG_HUGETLB_PAGE=y,否则改 grub 也没用 -
ls /proc/sys/vm/hugetlb_shm_group—— 文件存在才表示 hugetlbfs 子系统已激活
如果前三项任一失败,先检查内核配置或换支持 HugePages 的内核版本,别往下硬配。
为什么 echo 写入 /proc/sys/vm/nr_hugepages 经常不生效
因为 /proc/sys/vm/nr_hugepages 只是“申请额度”,不是“立刻分配”。内核会尝试从 buddy 系统里找连续的物理内存块(比如 2MB),失败就静默忽略。
- 现象:
echo 2048 > /proc/sys/vm/nr_hugepages返回成功,但cat /proc/meminfo | grep HugePages_Free没变 - 原因:内存碎片高(尤其运行数天后)、free -h 显示空闲但没连续 2MB 块、其他进程占着高端内存
- 解法只有两个:重启前静态配 grub(推荐),或开机后立刻执行,别等数据库/Redis 启动完再写
临时测试可用,但生产环境必须走静态分配路径。
Oracle/PostgreSQL 进程到底用没用上 2MB 大页
光看 HugePages_Free 减少了没用。很多场景下它减了,但进程实际走的还是 4KB 小页。
- 正确验证方式:
grep MMUPageSize /proc/<pid>/smaps</pid>—— 必须出现MMUPageSize: 2048且MMUPageOffset: 0 - Oracle 卡点:
use_large_pages=only(不能是auto),且启动用户ulimit -l必须是unlimited(写进/etc/security/limits.conf后需重新登录) - PostgreSQL 卡点:
huge_pages = on,且shared_buffers必须能被大页大小整除(如 8GB / 2MB = 4096,差 1 字节都会 fallback)
另外,shmmax 必须 ≥ 共享内存总需求,否则 ipcs -lm 里能看到硬限制卡住。
透明大页(THP)和标准 HugePages 能共存吗
技术上能共存,但生产环境必须关掉 THP。
-
cat /sys/kernel/mm/transparent_hugepage/enabled—— 输出必须含[never],[always]或[madvise]都不行 -
echo never | sudo tee /sys/kernel/mm/transparent_hugepage/enabled是 runtime 关闭,要持久化得加进/etc/rc.local或 systemd service - DPDK、Oracle、Redis 等明确要求 THP disabled,否则会干扰显式大页绑定逻辑,甚至导致性能更差
最易被忽略的是:即使你没主动开 THP,某些发行版默认是 always,不查不关,配了也白配。











