内存管理-72-THP-2-chatGPT


一、使能THP对性能和内存的影响

1. THP 带来的性能收益

--------------------------------------------------------------------------------------------------------------------
收益来源                机制                                                幅度
--------------------------------------------------------------------------------------------------------------------
TLB miss 减少           一个 TLB 条目覆盖 2MB(原来需要 512 个 4KB 条目)     TLB miss 率可降低 50-90%
页表开销减少             一个 PMD 条目替代 512 个 PTE 条目                    页表内存减少 ~512 倍(对该映射区域)
Page fault 次数减少     一次 fault 映射 2MB                                 fault 次数减少 512 倍
缓存友好                连续物理内存,硬件预取更高效                           依赖访问模式
--------------------------------------------------------------------------------------------------------------------

典型收益场景:大内存工作集的应用(数据库、JVM、浏览器渲染):5-10% 性能提升; 极端 TLB 敏感场景(遍历大数组):20-50% 提升; 小内存工作集应用:几乎无收益。

 

2. THP 带来的性能损耗

--------------------------------------------------------------------------------------------------------------------
损耗来源                机制                                                    幅度
--------------------------------------------------------------------------------------------------------------------
分配延迟                需要连续 2MB(order-9)物理页,可能触发 compaction        单次 fault 延迟从 ~5μs 增加到 ~100μs-数ms
khugepaged CPU 开销     后台线程不断扫描并合并 4KB 页为大页                       持续占用 1-5% CPU
内存碎片化压力            需要高阶连续内存,加剧碎片化                             间接影响所有分配
拆分开销                部分 unmap、swap out、MADV_DONTNEED 时需拆分            拆分一次 ~10-50μs
swap 放大               即使只修改 4KB,swap out 整个 2MB                      swap I/O 放大 512 倍(如果不拆分)
内存回收延迟             LRU 上是 2MB 的 folio,回收粒度大                       可能回收过多
compaction stall       分配时做 direct compaction 阻塞进程                     延迟毛刺
--------------------------------------------------------------------------------------------------------------------


3、THP内存消耗

3.1 内部碎片(最主要的消耗)

THP 以 2MB 为粒度分配。如果进程实际只需要 100KB,也会分配 2MB:
比如,进程 mmap 了 100KB 匿名内存:
    4KB 页面方式:分配 25 个 4KB = 100KB → 浪费 0
    THP 方式: 分配 1 个 2MB = 2048KB → 浪费 1948KB(95%!)

实际中不会这么极端(THP 只对 >= 2MB 对齐的 VMA 区域触发),但部分填充的大页仍然常见:

3.2 额外内存开销量化

---------------------------------------------------------------------------------------------------------------
开销项                    大小                                    说明
---------------------------------------------------------------------------------------------------------------
内部碎片                 每进程 0-几MB,系统级几十~几百 MB          取决于进程内存使用模式
页表节省                 负开销(节省内存)                        PMD 映射省了 PTE 页表页
khugepaged 工作内存      极小(< 1MB)                            扫描用的临时结构
struct page 元数据       无变化                                  无论是否 THP,每个 4KB 页都有 struct page
zero huge page          2MB(全局一个)                          用于 THP zero-fill
---------------------------------------------------------------------------------------------------------------

3.3 对 Android 的实际影响

(1) 未开 THP:
system_server RSS: ~400MB
Launcher RSS:      ~150MB
各 App 累计:       ~6GB
总 anonymous:      ~7GB

(2) 开启 THP (always):
system_server RSS: ~430MB  (+30MB, 内部碎片)
Launcher RSS:      ~160MB  (+10MB)
各 App 累计:       ~6.5GB  (+500MB, 内部碎片总和)
总 anonymous:      ~7.5GB  (+500MB ~ +1GB)

额外内存消耗预估:500MB - 1GB(16GB 设备的 3-6%)


4. 对 Android 的特殊考量

---------------------------------------------------------------------------------------
因素                 影响
---------------------------------------------------------------------------------------
App 生命周期短        App 频繁创建销毁,THP 分配的大块内存很快被释放,碎片化严重
zygote fork         fork 时 COW 以 THP 为单位,一个字节写入就要复制 2MB
LMKD 回收            杀 App 释放大页后碎片化,后续分配更难凑出连续 2MB
swap/zram            THP swap out 时需要写 2MB 到 zram,压缩比可能更差
小内存设备            16GB 设备浪费 500MB-1GB 可能导致更频繁的 LMKD 杀进程
---------------------------------------------------------------------------------------


5. 各使能模式对比

--------------------------------------------------------------------------------------------
THP 模式    性能影响                        内存额外消耗         适用场景
--------------------------------------------------------------------------------------------
always     收益最大,但延迟毛刺也最多         最高(+3-6% RAM)    大内存服务器、数据库
madvise    仅对显式声明的区域有收益          可控(应用按需)       折中方案、Android 推荐
never      无收益也无损耗                   无额外消耗           小内存设备、延迟敏感场景
--------------------------------------------------------------------------------------------


6. 对 16GB 设备的建议

16GB 设备:THP 额外消耗 ~500MB-1GB,16GB 中可用内存本就不算充裕(扣除内核/GPU/固件保留后可能只有 12-13GB),额外占 500MB ≈ 可用内存的 4%,Android 应用模式不太适合 THP(频繁 fork、短生命周期、COW 放大)

建议:16GB 设为 never 或 madvise,24GB 可考虑 madvise,32GB+ 可考虑 always

7. 评估THP实际影响

//查看 THP 使用情况
# cat /proc/meminfo | grep -i huge
AnonHugePages:   524288 kB //实际使用的 THP 大页内存
ShmemHugePages:       0 kB

//查看 THP 事件统计
# cat /proc/vmstat | grep thp
thp_fault_alloc 12345       //page fault 时成功分配 THP 次数
thp_fault_fallback 6789     //page fault 时 THP 失败退回 4KB 次数
thp_collapse_alloc 345      //khugepaged 合并成功次数
thp_split_page 234          //THP 被拆分次数

如果 thp_fault_fallback 很高,说明碎片化严重,THP 效果打折。如果 AnonHugePages 占比很大,说明内部碎片消耗高。

 

posted on 2026-08-25 18:22  Hello-World3  阅读(12)  评论(0)    收藏  举报

导航