目录
用惯了大内存处理器,最近因项目原因接触小内存的处理器。才有机会在内存泄露分析上认真学习下:
内核态内存泄漏查询:
vmalloc
分配大块内存,走budy system;通过cat/proc/vmallocinfo可以统计;
注:Cat vmallocinfo,如果有buffer块数一直在增加,则是内存泄露。
kmalloc/kmem_cache_create
分配小于pagesize,走slab机制;通过cat /proc/meminfo里的slab字段可以统计。
注: 如果怀疑有kernel mode内存泄露,运行应用过程中每间隔一段时间cat/proc/meminfo留意slab。如果一直在增加,大概率有内存泄露的可能。具体模块的函数泄露可以用kmemleak debug。
检查内存泄漏的方法 -- Kernel Space
Linux kernel 2.6.31 之后,提供了 KMEMLEAK 的选项,可以拿来测试 kernel modules是否有 memory leakage,用法整理如下。
修改 .config 设定 KMEMLEAK,重新编译 kernel,重烧 image。
摘录 .config 如下:
# Memory Debugging
CONFIG_HAVE_DEBUG_KMEMLEAK=y
CONFIG_DEBUG_KMEMLEAK=y
CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE=4096
确认板子上的 kernel 已经提供 kmemleak的功能。
# mount -t debugfs nodev /sys/kernel/debug/
# cat /sys/kernel/debug/kmemleak
注:若存在 kmemleak,表示 kernel 已经支援 kmemleak
用法举例
图2-1
cid:image003.png\@01D2DB8B.2E89DE10
注:若沒有手动执行 scan,系统每10分钟自动扫描一次 memory leakage.
实际测试 Driver memory leakage 的方法
# mount -t debugfs nodev /sys/kernel/debug/
# echo clear > /sys/kernel/debug/kmemleak
# run_your_driver_test_her
# echo scan > /sys/kernel/debug/kmemleak
用户态内存泄露
如果发现程序运行过程,meminfo里的Memfree有不断的减少,echo 3 > /proc/sys/vm/drop_cache也不会返回内存,大概率是有内存泄露。
在排除kernel space内存泄露的前提下,试试隔段时间观察cat /proc/PID/smap里每个so的堆。有一定机率能发现是哪个so内存泄露。
排查使用第三方工具分析内存泄露。dmalloc等等
内存查询常用指令
cat /proc/PID/status
cat /proc/meminfo
cat /proc/PID/maps
cat /proc/PID/smaps
cat/proc/vmallocinfo
这几条指令就不详细介绍了