内存管理调试方法
内存问题常见的类别
- 内存泄漏——内存malloc后未free(或者是有缓存未实际释放)
- 内存越界
- 内存重复释放
- 内存释放后还在使用
内存泄漏
分析和解决思路
采用分层定位法,明确泄露层级
- 系统层面初步判断泄露发生在:内核态 or 用户态 —— 大概率是用户态
- 确定是用户态之后,泄露进程 --> 泄露函数 --> 问题代码段
linux系统层面
meminfo
可以通过/proc/meminfo来查看系统内存使用情况如下,详细说明见:/proc/meminfo解读
[root@iZ2vc9tzeqqfy8lzwtvn1aZ ~]# cat /proc/meminfo
MemTotal: 3649004 kB
MemFree: 720336 kB
MemAvailable: 1878912 kB
Buffers: 209796 kB
Cached: 907400 kB
SwapCached: 14988 kB
Active: 695344 kB
Inactive: 1745148 kB
Active(anon): 49308 kB
Inactive(anon): 1292364 kB
Active(file): 646036 kB
Inactive(file): 452784 kB
Unevictable: 4 kB
Mlocked: 4 kB
SwapTotal: 2097148 kB
SwapFree: 2008684 kB
Dirty: 1568 kB
Writeback: 0 kB
AnonPages: 1315248 kB
Mapped: 1130364 kB
Shmem: 18376 kB
KReclaimable: 347364 kB
Slab: 412504 kB
SReclaimable: 347364 kB
SUnreclaim: 65140 kB
KernelStack: 5616 kB
PageTables: 23320 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 3921648 kB
Committed_AS: 2552812 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 17076 kB
VmallocChunk: 0 kB
Percpu: 8576 kB
HardwareCorrupted: 0 kB
AnonHugePages: 655360 kB
ShmemHugePages: 0 kB
ShmemPmdMapped: 0 kB
FileHugePages: 63488 kB
FilePmdMapped: 55296 kB
CmaTotal: 0 kB
CmaFree: 0 kB
DupText: 0 kB
MemZeroed: 0 kB
Unaccepted: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
Hugetlb: 0 kB
DirectMap4k: 384284 kB
DirectMap2M: 3643392 kB
DirectMap1G: 0 kB
[root@iZ2vc9tzeqqfy8lzwtvn1aZ ~]#
AnanPages、Mapped的和大致等于用户态消耗的内存:
AnonPages: 1315248 kB
Mapped: 1130364 kB
Slab是内核小内存的消耗:
Slab: 412504 kB
如果这两项都没有明显的增长,说明是内核buddy处泄露
决策流程图
MemAvailable 持续下降?
├─ 否 → 无泄漏
└─ 是 → drop_caches 后是否恢复?
├─ 是 → 缓存行为,非泄漏
└─ 否 → AnonPages+Mapped 是否同步增长?
├─ 是 → ✅ 用户态泄漏(查进程 RSS)
└─ 否 → SUnreclaim 是否同步增长?
├─ 是 → ✅ 内核 Slab 泄漏(查 /proc/slabinfo)
└─ 否 → 计算残差是否持续增长?
├─ 是 → ✅ 内核 Buddy 泄漏(查 alloc_pages 调用点)
└─ 否 → 检查 HardwareCorrupted / CmaUsed 等罕见字段