Linux 内存管理调试分析:ftrace、perf、crash 的系统化使用
Linux 内存管理调试分析:ftrace、perf、crash 的系统化使用
Linux 内核内存管理是构成整个内核性能和系统稳定性的基础,但这一子系统结构复杂,常常有设置失败、性能展示不良、OOM 杀进程等问题。要分析这些问题,需要一套工具化、实操化的技术路径,也就是 ftrace / perf / crash 等核心分析工具。
本文系统分析这三者如何配合 Linux 内存管理系统使用,应对“分页、物理分配、SLAB、回收、OOM” 等典型场景,帮助实际工程师实现“知其然,知其所以然”。
一、ftrace: 函数级调用进程观测
完全适用场景:
- 分析
do_page_fault()
触发流程 - 查看
__alloc_pages()
/kmalloc()
调用堆栈 - 追踪
kswapd
的执行路径 - 跟踪
tlb_flush
或zap_page_range
导致的异常性能开销
基本使用
# 启用 function_graph 跟踪
trace-cmd record -p function_graph -l do_page_fault
trace-cmd report | less
实战示例:深入 do_page_fault
缺页分析
在一次用户态访问大数组的性能瓶颈中,我们怀疑访问频繁缺页。
通过 ftrace:
trace-cmd record -p function_graph -l do_page_fault
然后在 report 中确认是否反复触发 handle_mm_fault()
→ __do_fault()
→ alloc_pages()
。
解析亮点:这是典型的“按需分配”场景,理解虚拟内存页未映射前会触发缺页中断,走 alloc_pages 去真正分配物理页。
面试官想听:你是否能清楚描述 page fault 的真正触发路径、每一级函数做了什么?是否能用 ftrace 工具亲自验证?
实战示例 2:跟踪 kswapd
中断页面回收路径
trace-cmd record -p function_graph -l shrink_node
在低内存触发 reclaim 时,你可以看到:
shrink_node
→ shrink_lruvec
→ shrink_inactive_list
→ try_to_unmap
→ tlb_flush_mmu
。
解析亮点:能清楚看出内核是怎样在后台异步 reclaim 页的,这对分析页面回收的成本至关重要。
二、perf: 确实量化的性能分析器
完全适用场景
- 分析 page fault 高变量原因
- 分析 slab 分配热点(kmalloc 或 obj_cache 较热)
- 分析 TLB 失效、cache miss 对性能影响
- 分析 swap 带来的写回延迟
实战示例:判断 SLAB 是否频繁分配回收
在一次内核模块加载中频繁分配小块内存,怀疑 kmalloc 压力大。
perf top
结果发现 kmalloc
/kmem_cache_alloc_node
占比很高。
进一步定位:
perf record -e kmem:kmalloc -a
perf report
解析亮点:你不仅能看到热点函数,还能通过事件采样定位“谁分配得多、在哪里分配”,这才是 perf 真正的价值。
实战示例 2:统计缺页中断和 TLB Miss
perf stat -e page-faults,dTLB-load-misses ./test_app
- page-faults 很高,说明访问了大量未映射虚页。
- dTLB-load-misses 很高,说明频繁跨页访存,可能是内存碎片严重。
面试官想听:你是否能通过 perf 读出 cache miss、TLB miss 与内存管理之间的性能因果链。
三、crash: 实时和崩溃后的内核内存透视
完全适用场景
- 分析崩溃前 mm_struct / page / slab 状态
- 分析正在运行进程内存分布
- 分析不同 zone 的 free_area 分配情况
- 分析 Page flags,定位 dirty/unreclaimable 页面
实战示例:OOM 发生时定位原因
系统触发 OOM,dmesg
中仅提示 “invoked oom-killer”,如何找出问题?
crash /usr/lib/debug/vmlinux /proc/kcore
ps -g # 查看谁被杀
kmem -s # 查看 slab 内存是否泄漏
kmem -z # 查看各 zone 空闲状态
vm # 检查进程虚拟内存布局
解析亮点:通过 crash 工具还原当时内存整体状态、对象分配情况,进而判断是否因 unreclaimable slab 太大而触发 OOM。
实战示例 2:分析 zone 空闲页不足的原因
kmem -z
输出:Zone Normal 空闲页数只有 4,而 highmem 有上千页,但系统使用默认 GFP_KERNEL(只能分配 Normal),因而无法满足大页请求。
面试官想听:你是否能理解 zone 的内存不可跨分配导致的“假空闲”,以及如何定位。
四、应用场景组合指南
情况一:内存清理性能差,系统卡顿
- 用
perf stat -e page-faults,dTLB-load-misses
- 用 ftrace 追踪
do_page_fault
/shrink_node
- 用
crash
分析 zone 分配情况
情况二:内核 OOM Kill 不明原因
dmesg
看 OOM 输出crash
分析oom_score
对比- 观察 swap + reclaim 操作是否不该触发
情况三:SLAB 分配压力大
perf top
看 kmalloc / cache 热点crash kmem -s
观察小对象分配热点- 分析 slab 是否无法回收,或分配深度
情况四:TLB/Cache 异常导致延迟跳变
- perf 分析 dTLB-load-misses, cache-misses
- ftrace 跟踪
tlb_flush_mmu()
- crash 查看 page.flags 是否为 dirty + active 状态,不能回收
第五、结论
Linux 内存管理子系统的处理路径、分配分析、回收策略和性能特性,都能通过 ftrace / perf / crash 做到系统化分析和跟踪。
从“规模规则 → 观察触发 → 分析排查”的线路出发,将理论知识、性能指标和实际调试完美一体化,才是真正理解 Linux MM 子系统的路径。