news 2026/10/22 19:07:03

大页怎么选?从TLB、访问方式到内存优化实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
大页怎么选?从TLB、访问方式到内存优化实践

写这种内存优化类的稿子,最容易出现的情况就是:查了一堆资料,最后发现“4KB 是默认,2MB 是大页,1GB 更大”,然后就不知道怎么选了。我前几年做某模拟项目 X 的内存调优时被问得最多的问题就是:“我这个业务到底该不该开大页?开了 2MB 还是 1GB?” 最后踩了不少坑才总结出一套判断逻辑:页面大小从来不是越大越好,关键看你的访问方式能不能“吃满”这个大页的覆盖范围。

这篇内容从 TLB 和页表这些最底层的机制讲起,然后按顺序扫描、随机访问、DMA、稀疏分配这几类典型访问方式逐一拆解,最后给出可落地的配置步骤和排查经验。适合正在做数据库、搜索、网络网关、内存缓存类服务的开发同学,也适合被线上内存延迟毛刺折磨的运维和 SRE 参考。

1. 物理页面大小为什么是个问题:从 TLB 说到页表开销

1.1 一次普通内存访问,CPU 到底干了多少活

现代操作系统用虚拟内存管理进程地址空间,程序访问的是虚拟地址,CPU 拿到虚拟地址后要去查页表才能得到物理地址。这个“查页表”的过程叫 page table walk。物理内存被切成固定大小的页面,页表里每一行记录一个虚拟页到物理页的映射关系。

标准 x86_64 下默认物理页面大小是 4KB。一个 128GB 内存的机器,如果全部用 4KB 页面,就会有 33554432 个物理页,理论上需要 3000 多万条页表项来映射。一条页表项占 8 字节,光一级页表就几百 MB。内核不会一口气把全部页表都建出来,但这些页表项在内存大、进程多的时候确实会吃掉不少物理内存。

更关键的是,CPU 不会每次访问都跑到内存里去翻页表,那样太慢。CPU 内部有一个专门缓存页表映射结果的硬件,叫 TLB。TLB 的容量非常小,L1 TLB 常见就几十到一百多条。4KB 页面下,就算 TLB 有 128 条,它也最多覆盖 512KB 的地址空间。如果你的程序工作集超过 512KB,TLB 就会频繁不命中,CPU 只能重新走页表查找流程。

换成 2MB 大页后,一条 TLB 记录可以覆盖 2MB 内存。128 条 TLB 记录就是 256MB 覆盖范围。1GB 大页就更夸张,几十条就能覆盖几十 GB。这就是大页最直观的价值:让有限的 TLB 记录覆盖更大的内存工作集。

1.2 页表层级也会随之变化,这不是小事

x86_64 的页表是四级结构(PML4、PDPT、PD、PT)。4KB 页需要走完全部四级才能拿到物理地址。2MB 大页只需要走到第三级,1GB 大页只需要走到第二级。page table walk 层级减少,意味着即使发生 TLB miss,重新填充 TLB 的开销也更小。

我用一个生活化的类比:4KB 页面就像一本 3000 页的电话簿,你要找到某个电话,只能一页一页翻,翻到哪一页只记 4KB 的内容;2MB 页面像一本 128 页的大册子,每页信息密度更高,翻的次数更少;1GB 页面就是一张大挂图,一眼扫过去覆盖全部。CPU 翻页表就是做这种“翻目录”的动作,目录越薄,翻得越快。

这也是为什么有些场景明明顺序访问的内存不大,大页也能带来收益——不是省了 TLB miss,而是省了 page table walk 本身的开销。

1.3 访问方式才是决定性变量

大页听起来全是优点,但内存分配是有代价的。4KB 页分配粒度小,内存碎片少,回收灵活,申请/释放都很轻。2MB 页要在物理内存里找一段连续 2MB 空间,系统跑久了内存碎片化严重的时候,这个操作可能失败。1GB 大页更苛刻,几乎只能在系统启动早期预留,运行中分配基本靠运气。

所以问题就变成了:你的程序访问内存的方式,能不能把大页的 TLB 覆盖优势用好?如果数据是随机撒在内存各处的,2MB 页和 4KB 页的 TLB 命中率可能差不了多少,但大页造成的内存浪费却实实在在。

顺序访问、随机访问、流式读取、稀疏填充、DMA 设备访问,这些访问方式对应的最优页面大小完全不一样。下面逐个拆开说。

2. 访问方式决定页面大小:几个典型场景的页大小表现

2.1 顺序扫描和流式读取:大页活得最滋润

顺序扫描是最适合大页的访问方式之一。典型场景是列存数据库的整列扫描、日志文件顺序解析、全量导出归档。程序沿着连续虚拟地址一路读下去,访问到的物理页也是连续的,TLB 顺着顺序一路覆盖,几乎不会出现反复 miss 同一段地址的情况。

而且顺序访问通常有硬件预取器在帮忙,CPU 会自动把后续几个 cacheline 拉进来。有人在 4KB 页面下测顺序扫描,TLB miss 率本身就不高,因为预取器替你掩盖了很多问题。换成 2MB 大页后,TLB 覆盖范围直接扩大 512 倍,页表从四级变成三级,page table walk 次数也下降,整体吞吐一般能提升 5% 到 15%,具体看内存带宽是否已经饱和。

我在模拟项目 X 里做过一个列存文件扫描测试:一个 2GB 的连续数据文件,4KB 小页下 dTLB-load-misses 约 3800 万次,换成 2MB 大页后降到 270 万次,吞吐提升了 12%。收益确实是正的,但如果你的程序已经跑到了内存带宽瓶颈,大页的提升就没那么明显,别指望靠它逆天改命。

2.2 随机访问、指针追逐、索引遍历:收益看数据的局部性

随机访问是很多人开大页的初衷,但也是最容易踩坑的地方。拿内存哈希表举例:key 通过哈希函数散列到整个 buckets 数组,访问 order 完全随机。4KB 页面下,你访问 100 万个 key,可能落在几十万个不同页面里,TLB 一路 miss。换成 2MB 大页,如果这 100 万个 key 恰好在同一个 2MB 连续区域内,TLB 覆盖显著提升,性能有很大改善。

但关键就在这个“如果”上。如果哈希表的 bucket 数组虽然连续,但 key 的热点数据分散在多个大页区域,甚至跨越几十 GB 内存,大页的 TLB 命中率不会比小页好多少。我实测过一个内存 KV 缓存:300MB 数据分布在 150 个 2MB 大页里,TLB miss 率下降了 40%,但内存从 320MB 涨到 520MB,因为每个大页内部都有大量空洞。

所以随机访问场景的判断标准不是“随机”两个字,而是数据在虚拟地址空间里的聚集程度。连续预分配的大数组 + 随机下标访问,大页收益明显;多个小对象各自 new 出来、分散在不同堆区域,大页不一定有用。

2.3 大量小对象频繁创建销毁:小页才是正道

如果你的服务是典型的网络网关、短连接处理、消息队列消费,内存里全是生命周期极短的小对象,我不建议你开大页。原因很简单:大页的最小分配单位是 2MB,一个小对象池如果用大页承载,意味着你要用 2MB 的粒度去管理原本几百字节的对象。分配器不得不在这块 2MB 区域内做细粒度切分,管理成本更高,页内碎片也更严重。

THP(透明大页)在 always 模式下会尝试把进程堆里的连续小页合并成大页。这个过程由 khugepaged 内核线程在后台做,它会扫描内存、移动物理页、修改页表。扫描期间可能造成亚毫秒级甚至毫秒级的延迟尖峰。对于低延迟交易类服务,这往往比 TLB miss 更致命。

这类场景我建议保持 4KB,或者用 madvise 模式只对明确标注的区域启用大页。不要为了“优化”把所有小对象内存都搞成大页,那是给 allocator 添乱。

2.4 DMA 和设备映射:连续物理内存才是硬需求

DMA 场景和前面的 CPU 访问不太一样。设备发起 DMA 时,驱动需要把一段物理连续的内存映射给设备。4KB 页能保证小粒度连续,但大块连续的物理内存往往需要多个页拼接,驱动逻辑复杂,IOMMU 页表也大。这块用 2MB 大页能显著减少 IOMMU 页表项数量,降低 DMA 映射开销。

典型例子是虚拟化场景里,虚拟机的内存映射使用大页后,宿主机和虚拟机之间的地址转换开销会小很多。KVM 的透明大页就是这么用的。如果你在裸机上直接操作网卡多队列的 DMA ring buffer,驱动通常要求连续物理页,配置大页缓冲池也能减少分配失败概率。

但这块有一个很隐蔽的问题:DMA 设备对物理地址的宽度可能有限制(比如某些老设备只支持 32 位地址),1GB 大页的物理地址未必适合所有设备。实施前一定要确认设备支持的地址范围,别把大页预留到设备看不到的内存区域。

2.5 稀疏访问和内存稀疏填充:内部碎片会吃光利润

另一种典型的“大页陷阱”是稀疏填充。比如一个全局位图、Bloom Filter、稀疏数组,你只写满了其中很小一部分,剩下的全是空洞。4KB 页面下你只为用到的部分分配内存;2MB 页面下,只要碰了一页的某个字节,整个 2MB 页都被算进 RSS。如果这个数组只有几十 MB 大小且互相隔离,每个部分恰好跨越半个大页,内存膨胀一倍都不奇怪。

这种场景我的建议是:先按“有效数据分布范围”计算一下内部碎片率。假如实际有效数据只有 30%,开大页后内存却翻了三四倍,那 TLB miss 再低也补不回来。内存本身不够宽裕的时候,先算账再动手。

2.6 各类访问方式页面大小选择速查

访问方式典型业务特征推荐页面大小主要收益主要风险
顺序扫描 / 流式读取全表扫描、日志归档、文件分析2MB 大页TLB 覆盖宽,页表层级少内存浪费少,风险低
随机访问(数据连续分布)大数组随机下标、索引遍历2MB 大页TLB miss 大幅下降大页分配失败
随机访问(数据离散分布)哈希表、小对象图遍历4KB 或 madvise 局部大页不确定内部碎片严重
大量小对象创建销毁网关、消息队列、短连接4KB,关闭 THP避免分配延迟尖峰无
DMA / 设备映射网卡 ring buffer、虚拟化内存2MB 大页减少 IOMMU 页表开销地址宽度限制
稀疏填充Bloom Filter、稀疏位图4KB避免内存膨胀无
超大工作集数据库缓冲池内存数据库、大缓存1GB 大页(内存 64GB+)单个 TLB 覆盖 GB 级预留困难,回收困难

这张表是我这几年的经验汇总,不是绝对标准,但可以作为第一轮判断的入口。

3. 动手前先做诊断:确认你的访问方式和优化空间

3.1 用 perf 量化 TLB Miss,别靠感觉

在改页面大小之前,先看数据。Linux 下 perf 可以直接采样 TLB miss 事件。跑一轮线上负载或者压测,命令类似:

perf stat -e dTLB-load-misses,dTLB-store-misses,itlb_misses ./your_benchmark

输出里会给出总量。还有个更科学的指标是 TLB miss 占访存指令的比例。如果你看到 dTLB-load-misses 每 1000 条 load 指令就有几百次 miss,说明 TLB miss 是主要瓶颈之一。如果 miss 率极低,比如千分之几,那大页大概率帮不上什么忙。

这里要提醒一句:不同 CPU 的 TLB 事件名称不完全一样,Intel 和 AMD 也有差异,按自己机器的 PMU 支持情况来找事件名。perf list 可以列出当前 CPU 支持的所有事件。

3.2 检查进程虚拟内存布局和工作集

perf 告诉你 TLB miss 有多严重,但没告诉你数据是怎么分布的。可以看/proc/<pid>/smaps和/proc/<pid>/numa_maps。

grep -E "Rss|AnonHugePages|VmSize" /proc/<pid>/smaps

重点关注两个信号:一是 RSS 总量和工作集是否接近;二是 AnonHugePages 字段有没有增长。如果你开了 THP 但 AnonHugePages 一直是 0,说明内核没成功合并页面,大概率是物理内存碎片太多,khugepaged 找不到连续的 2MB 块。

再用pmap -X <pid>看进程地址空间里的映射分布。如果发现大块连续映射占了大半 RSS,那开大页的空间是有的;如果全是几十 KB、几百 KB 的小映射,开大页的意义就要打个问号了。

3.3 建立一个可复用的 A/B 测试协议

我建议所有内存调优都走同一套流程,避免优化了个寂寞。流程如下:

  1. 固定压测模型和数据集,数据集大小要覆盖真实工作集的 80% 以上。
  2. 先在默认 4KB 下跑三轮,取 P50 和 P99 延迟、吞吐、TLB miss 数。
  3. 切到 2MB 大页,同样跑三轮。
  4. 对比吞吐、P99 延迟、内存 RSS 变化。

关键点:压测时间不要太短,至少跑 5 分钟以上。有些服务的 TLB miss 在启动预热阶段和稳定运行阶段差异很大,只跑 30 秒很容易得出错误结论。我遇到过某服务预热 3 分钟后 TLB miss 率掉了 70%,5 分钟压测才看得出来真实收益。

4. 实操选择:2MB、1GB 和动态策略到底怎么定

4.1 2MB 大页是多数场景的甜点位

大部分业务场景,我建议直接从 2MB 大页开始试。2MB 在 x86_64 体系里是 CPU 原生支持的第二级大页(HugeTLB 或 THP 都支持),分配要求没有 1GB 那么苛刻,回收也比 1GB 容易。数据库缓冲池、搜索引擎的倒排索引、持久化缓存这类动辄几百 MB 到几十 GB 的大块内存,2MB 足够覆盖 TLB 的收益。

分配和管理 2MB 大页要预留多少内存,可以按进程实际 RSS 估算,再加 20% 缓冲。比如某服务 RSS 稳定在 12GB,预留 15GB 的 2MB 大页就够用了,也就是nr_hugepages=7680。

4.2 透明大页 THP:always、madvise、never 怎么选

THP 最方便的地方是不用改代码,内核自动帮你合并小页。但“自动”也是一把双刃剑。三种模式各有利弊。

always 模式会尽量对所有匿名内存做大页合并,适合内存充足、内存分配模式简单的大数据处理服务。但正如前面说的,khugepaged 后台合并可能带来延迟毛刺。我们做过真实统计:某服务在 always 模式下,P99 延迟从 2ms 涨到 3.8ms,原因是合并线程扫描时触发 cgroup 限流和内存迁移。

madvise 模式是我最推荐的折中方案。只有程序显式调用madvise(MADV_HUGEPAGE)的区域才会被合并成大页,其他内存保持 4KB。这样既能让关键数据结构享受大页红利,又不会让所有小对象分配被卷进来。

never 模式适合实时性和确定性要求极高的系统。干脆关掉大页合并,避免一切后台行为。如果你已经用显式 hugetlb 管理关键内存,THP 完全可以关掉。

切换方式:

echo madvise > /sys/kernel/mm/transparent_hugepage/enabled echo madvise > /sys/kernel/mm/transparent_hugepage/defrag

注意 defrag 参数也很重要,它控制 khugepaged 是否会在分配时进行同步内存压缩。追求低延迟的话,defrag建议设为madvise或never,否则内存紧张时它会主动帮助迁移页面,引发额外延迟。

4.3 显式 Hugetlb:可控性最强的方案

如果不想让内核自动干预,可以走显式 hugetlb 路线。步骤很清晰:

  1. 预留大页:
sysctl vm.nr_hugepages=7680 # 7680 * 2MB = 15GB

更稳妥的方式是在内核启动参数里加hugepagesz=2M hugepages=7680,这样系统启动早期就从连续物理内存预留好了,不用担心运行中碎片导致预留失败。

  1. 挂载 hugetlbfs:
mkdir -p /mnt/hugepages mount -t hugetlbfs hugetlbfs /mnt/hugepages -o pagesize=2M
  1. 应用代码通过 mmap 使用大页:
#include <sys/mman.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> #define HUGEPAGE_SIZE (2 * 1024 * 1024) int main(void) { size_t len = 1024UL * 1024 * 1024; /* 1GB */ void *addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0); if (addr == MAP_FAILED) { perror("mmap hugepage"); return EXIT_FAILURE; } /* 使用 addr */ munmap(addr, len); return 0; }

如果不想用 MAP_HUGETLB,也可以直接在 hugetlbfs 挂载目录里open一个文件再mmap它,效果一样。

显式 hugetlb 的优点是完全没有后台合并线程的干扰,内存分配是一次性的,稳定。缺点是预留的内存不能被其他进程使用,也就是说这些大页从你预留开始到释放为止,一直占着物理内存。如果服务内存泄漏或者负载突降,这块内存就浪费了。

4.4 1GB 大页:什么情况才值得上

1GB 大页是核武器,不能乱用。它适合单进程工作集以 GB 为最小单位的场景,典型是内存数据库的 buffer pool、超大规模机器学习模型的 embedding 表、需要极低 TLB miss 的 HPC 计算。

1GB 大页的问题很明显:分配只能在启动早期做,预留后基本无法拆分给其他用途;物理内存必须连续 1GB,碎片化以后很难找到那么多块;进程之间如果共享同一块 1GB 区域,管理复杂。还有,不是所有 CPU 都默认支持 1GB 页,需要 CPU 的 PDPE 位开启,虽然现代服务器基本都支持,但桌面和一些低端处理器未必。

我自己只在物理内存 256GB 以上的数据库节点上用过 1GB 大页,普通 32GB 内存的机器完全没必要。小块数据用 2MB 已经足够把 TLB miss 压到很低,1GB 是给超大工作集准备的。

4.5 NUMA、内存锁、预留:容易被忽视的配套工程

大页不是孤立参数,它和 NUMA 策略、内存锁绑定在一起。

先说 NUMA。大页分别从哪个 NUMA 节点分配,直接影响跨节点访问延迟。分配大页时更推荐用numactl或者 cpuset 固定的方式,让进程绑在 CPU 所在节点上,然后再从该节点预留大页。不指定 NUMA 的话,内核可能把 2MB 大页分散到多个节点,程序访问时就容易出现一半本地访问一半远程访问,白白损失延迟。

再说内存锁。大页本身就接近不可换出,但显式 hugetlb 内存如果不加mlock,内核在某些极端内存压力下可能还是会让它参与回收。保险起见对大页区域执行:

mlock(addr, len);

注意mlock受 RLIMIT_MEMLOCK 限制。默认限制可能只有 8MB,如果服务要锁几十 GB 大页,需要调高:

ulimit -l unlimited

这个操作在 systemd 管理的服务里要在 unit 文件里配 LimitMEMLOCK=infinity,否则服务起来以后锁内存直接失败,大页白配。

5. 多场景真实效果复盘:大页带来的红利和浪费都有多大

5.1 顺序扫描场景:收益稳定但不是神话

模拟项目 X 里我测过一个列式存储的扫描模块,每次全表扫描 2GB 数据。默认 4KB 页面下 TLB miss 率约 0.4%,吞吐 1.8GB/s。开到 2MB 大页后 TLB miss 率降到 0.05%,吞吐升到 2.0GB/s,提升约 11%。内存占用没有明显变化,因为顺序扫描的数据是密集的,几乎不存在内部碎片。

这个场景的特点是大页收益稳定、风险低。如果你的业务也是大文件连续读,2MB 大页可以无脑上。

5.2 哈希索引场景:红利大但内存也涨得快

模拟项目 Y 是一个内存哈希索引服务,数据量 500MB。4KB 下 dTLB-load-misses 每 1000 次访问约 42 次,P99 延迟 1.1ms。换 2MB 大页后 TLB miss 降到 12 次,P99 延迟降到 0.7ms,性能提升约 35%。看起来很美好,但 RSS 从 520MB 涨到了 720MB,内部碎片多了 200MB。

原因很简单:哈希桶数组虽然连续,但数据填充后很多 2MB 大页只有一部分被占用。 这对内存充足的服务是划算的,但对内存紧张的容器来说,就要统一权衡了。我的建议是:如果内存水位本来就在 70% 以下,可以用大页吃性能红利;如果内存水位长期 85% 以上,大页可能导致 OOM。

5.3 短连接网关场景:THP 带来的延迟毛刺

有客户线上一个消息网关,处理大量短连接。默认 always 模式下,P99 延迟偶尔飙到 20ms 以上,压测时尤其明显。我们用 perf 定位到是 khugepaged 在扫描合并页面,触发内存迁移操作。把 THP 改成 madvise 并关掉相关代码路径后,P99 回到 1.2ms,毛刺彻底消失。

这类场景的教训是:不是所有内存都适合大页,小对象频繁创建销毁的业务,THP 的“自动优化”反而是定时炸弹。

5.4 虚拟化和容器场景

虚拟机场景里,大页的收益来自两处:一是虚拟机内存映射使用 2MB 大页,宿主机 KVM 的页表项减少;二是客户机内部如果也用大页,双层页表开销都会下降。实测一个 4 核 8GB 的虚拟机,开大页后虚拟化层 TLB miss 下降了约 20%。

但容器环境要注意:容器本身的内存限制 bash cgroup 是以 4KB 页为记账粒度的,如果容器里使用大页,RSS 统计可能瞬间冲高,导致 cgroup 误判内存超限。容器场景下,我建议谨慎使用透明大页,优先考虑给整个节点做预留,再让容器通过 hugetlbfs 绑定。

5.5 长周期运行后的碎片问题

大页系统跑久了最怕碎片。物理内存被各种大小映射切得支离破碎,后续预留大页很容易失败。/proc/buddyinfo可以看物理内存的空闲块情况,如果某个 order 以上的连续块很少,说明碎片化严重。

建议在大页方案上线后,每周记录一次 MemFree、HugePages_Total、HugePages_Free 这几个指标。一旦发现大页 free 数持续为零,而业务明明没有涨,就要考虑是不是有人占了不还。

6. 常见坑与排查:页面大小改动引发的线上事故

6.1 预留过大导致其他进程吃不上内存

最常见的事故是把大页预留当成“内存越大越好”,结果某节点预留了 60GB 1GB 大页,业务只用了 30GB,剩余 30GB 谁也动不了,系统内存被大量浪费,其他进程只能挤在小页区域里频繁 swap。

处理办法:先按实际业务内存的 70% 预留,留足系统其他进程的余量。预留大页后,/proc/meminfo里的 HugePages_Total 不等于可用系统内存,要时刻提醒自己——这部分是“冻结资产”。

6.2 THP 合并在后台造成的延迟毛刺

前面说过的网关问题再提一次:THP 的扫描、迁移和折叠是后台行为,但它会打断应用访问内存,造成幅度不小的暂停。如果你发现开启 THP 后服务的 P99 延迟曲线出现周期型尖峰,大概率就是 khugepaged 在干活。

排查方法:

ps -eo pid,cmd,pcpu | grep khugepaged

正常它占用很低,如果它 CPU 跑来 10%,说明内存碎片多、合并频繁。对策一是关 THP,二是加大内存预留降低碎片,三是对高频路径用 madvise 锁定。

6.3 mlock 限制导致内存锁定失败

显式 hugetlb + mlock 时,经常出现mmap成功但mlock返回 EAGAIN 的情况。典型原因是进程的 RLIMIT_MEMLOCK 太低。不是内核不给锁,是进程自己的 rlimit 不够。排查:

ulimit -l

如果是 8MB,那一个大页就超了。用 systemd 的话要配LimitMEMLOCK=infinity。docker 容器里还要看 docker 的 memory lock 设置。

6.4 只关心 TLB miss,忽略页表本身的内存和 CPU 开销

有些系统管理员开大页是为了减少页表内存,但忘了页表本身也是要 CPU 时间去更新的。进程频繁 fork 时,子进程要复制父进程页表,页表项越多 fork 越慢。大页能明显减少页表项数量,这就是为什么 Java 服务开启-XX:+UseLargePages后有部分收益其实是 fork/exec 变快了。

反过来,如果服务用 madvise 把大量小对象也标注成大页,页表少了但大页分配和回收路径更慢,整体未必赚。

6.5 排查命令速查表

检查项命令判断标准
大页总量和剩余grep Huge /proc/meminfoHugePages_Free 不足则预留不够
进程 THP 是否生效cat /proc/\<pid\>/smaps | grep AnonHugePages有大段 AnonHugePages 说明合并且成功
物理碎片状态cat /proc/buddyinfoorder>=9 的连续块少则大页分配困难
TLB miss 采样perf stat -e dTLB-load-misses ...miss 率与基线对比
khugepaged 负载ps -eo pid,cmd,pcpu | grep khugepagedcpu 偏高说明 THP 扫描频繁
进程内存锁限制ulimit -l必须大于需要锁定的内存

6.6 我的最后一条经验:从诊断开始,从回滚预案结束

所有生产环境的大页改动都要先做好回滚预案。因为大页预留和 THP 开关在运行时可以动态调整,但页面合并不可能瞬间反转——已经合并成 2MB 的物理内存要重新拆回 4KB,需要内核扫描和迁移,这个过程可能持续几秒甚至几分钟,期间服务仍受影响。

我在线上做过最稳妥的流程是:先在测试环境完整跑 A/B,再挑一台低峰期的生产节点灰度,观察一天再扩大。如果出现问题,先把 hpage 参数回滚,再等待内存回收。宁可用 4KB 慢一点,也不要因为大页把服务拖死。

说实话,物理页面大小这个参数在优化列表里并不起眼,但它撬动的是 TLB、页表、内存分配器、NUMA 策略好几层系统机制。不同访问方式面前,大页有时候像涡轮增压,有时候像给小型车装了个飞机引擎。希望这篇内容能让你下次面对“该不该开大页”这个问题时,心里先有个清晰的判断框架,而不是看到“大页”两个字就盲冲。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/22 19:06:05

uniapp选课系统实战:跨端架构、MySQL事务与真机避坑指南

简介&#xff1a;本资源是一套面向高校计算机专业本科生的毕业设计/课程设计级移动端选课系统完整实现&#xff0c;聚焦教育信息化场景&#xff0c;解决传统选课流程中学生选退课不便、教师课程管理低效、教务数据分散等实际问题。资源包共978个文件&#xff0c;32.87MB&#x…

作者头像 李华
网站建设 2026/10/22 19:04:32

手写Tool Use三方案:原生调用、JSON Mode与Prompt解析

面试官把题目亮出来的时候&#xff0c;我愣了一下&#xff1a;“现在让你手写一个 Tool Use&#xff0c;你打算怎么实现&#xff1f;”注意&#xff0c;是“手写”&#xff0c;不是“调用某个厂商平台的现成 SDK”。Tool Use&#xff0c;也就是让大模型学会使用外部工具&#x…

作者头像 李华
网站建设 2026/10/22 19:03:25

华三交换机堆叠实战:IRF配置、MAD检测与运维避坑指南

1. 堆叠不是插上线就完事&#xff1a;先搞清楚它到底解决什么问题 很多人第一次接触交换机堆叠&#xff0c;脑子里想的都是"把几台设备用线连起来&#xff0c;端口翻倍就完事了"。我刚开始也是这么理解的&#xff0c;直到有一次在机房里折腾到凌晨两点&#xff0c;才…

作者头像 李华
网站建设 2026/10/22 19:02:32

专科毕业论文全流程AI工具指南:从选题到答辩的8类实用助手

毕业论文这四个字&#xff0c;对很多专科生来说&#xff0c;比毕业实习还让人头大。选题没方向、文献看不懂、查重总超标、格式反复被退回、答辩怕被问倒——这些坑我基本都踩过一遍。后来我把市面上能接触到的AI论文工具系统过了一遍&#xff0c;按论文全流程整理出8个最实用的…

作者头像 李华
网站建设 2026/10/22 19:01:26

AI Agent从工具到行动者:核心架构、落地实践与避坑指南

1. 从“工具”到“行动者”&#xff1a;这个判断到底在说什么“AI正从工具变成行动者”&#xff0c;这句话第一次听到的时候&#xff0c;我第一反应是&#xff1a;又是一个概念包装。但仔细琢磨了一下最近半年我自己在项目里用Agent的体验&#xff0c;不得不承认&#xff0c;这…

作者头像 李华
网站建设 2026/10/22 19:01:05

Suno AI音乐生成实战:从提示词到完整歌曲的工程化指南

1. 从一段旋律到一款产品&#xff1a;音乐生成赛道的真实门槛 第一次听到AI生成的完整歌曲时&#xff0c;我正蹲在工作室里调一段鼓组。朋友甩过来一个链接&#xff0c;说“你听听这个&#xff0c;人声、编曲、混音全是一键出来的”。我点开&#xff0c;前奏的钢琴音色干净得不…

作者头像 李华