青囊,喜欢运动T恤加皮裤的非典型程序猿。此时,他正目不转睛注视着屏幕上一行行的代码,内存泄漏这个问题已经让他茶饭不思两三天了,任凭偌大的雨滴捶打着窗户也无动于衷。就这么静悄悄地过了一会儿,突然间,他哼着熟悉的小曲,仿佛一切来的又那么轻松又惬意。
小白的练级之路少不了前辈们的语重心长。从踏上linux内核之路开始,专家们就对青囊说——“遇到困难要学会独立思考”、“最好的学习方式就是带着问题看代码”等等。可这次遇到的问题,让青囊百思不得其解——机器总内存有200G,运行800多天,slabUnreclaim占用 2G,且停掉业务进程,内存占用并没有降低。客户非得让青囊给出合理解释:
1.slab 2G内存是否存在泄漏?如果存在泄漏需要找到原因。
2.如不存在泄漏,需要找到这2G的使用者。
echo scan > /sys/kernel/debug/kmemleak
cat /sys/kernel/debug/kmemleak
#echo scan > /sys/kernel/debug/kmemleak
bash: /sys/kernel/debug/kmemleak: Permission denied
#ls -l /sys/kernel/debug/kmemleak
ls: cannot access /sys/kernel/debug/kmemleak: No such file or directory
# CONFIG_DEBUG_KMEMLEAK is not set
内存的内容不会再改变, 因为没有进程能访问到这块内存。
slab的object内存对象,可能会残留使用过的全局变量, 函数名,字符串,指针,特定数值(垃圾满地)。
内存中充斥着大量内容相似(相等)的slab object对象。
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
419440512 419440512 100% 0.03K 3276879 128 13107516K kmalloc-32
810303 401712 49% 0.10K 20777 39 83108K buffer_head
417600 362397 86% 1.05K 13920 30 445440K ext4_inode_cache
267596 241915 90% 0.57K 9557 28 152912K radix_tree_node
216699 154325 71% 0.19K 10319 21 41276K dentry
155958 37367 23% 0.04K 1529 102 6116K ext4_extent_status
crash> kmem -S kmalloc-32 | tail
ffffea000c784e00 ffff88031e138000 0 128 111 17
ffffea00242d0240 ffff88090b409000 0 128 126 2
ffffea00436c5800 ffff8810db160000 0 128 127 1
ffffea0018b1df40 ffff88062c77d000 0 128 126 2
ffffea005947d1c0 ffff881651f47000 0 128 126 2
ffffea004d463080 ffff8813518c2000 0 128 126 2
ffffea0030644100 ffff880c19104000 0 128 126 2
crash> rd ffff88031e138000 -S
ffff88031e138000: ffff882f59bade00 dead000000100100 ...Y/...........
ffff88031e138010: dead000000200200 ffffffff002856f7 .. ......V(.....
-------
ffff88031e138020: ffff882f59bade00 dead000000100100 ...Y/...........
ffff88031e138030: dead000000200200 ffffffff00284a2a .. .....*J(.....
------
ffff88031e138040: ffff882f59bade00 dead000000100100 ...Y/...........
ffff88031e138050: dead000000200200 00303038002856f7 .. ......V(.800.
------
ffff88031e138060: ffff882f59bade00 dead000000100100 ...Y/...........
ffff88031e138070: dead000000200200 ffffffff00284a29 .. .....)J(.....
crash> x /20a 0xffff882f59bade00
0xffff882f59bade00: 0x460656b7 0xffffffff81685b60
0xffff882f59bade10: 0x63ea63ea00000001 0xffff882f59bade18
0xffff882f59bade20: 0xffff882f59bade18 0x0
0xffff882f59bade30: 0x0 0xffff882f59bade38
0xffff882f59bade40: 0xffff882f59bade38 0x7fb27fb2
自动判断系统是否存在泄漏。
自动判断是slab, vmalloc还是alloc page泄漏。
扫描全局内存,找到内存中slab object最多,且内容相似度最高的object。
动态采集内存的分配和释放。
计算动态采集地址的内容与存量object的内容相似度,但达到一定相似度时,则对动态地址进行标记。
未释放内存汇总:
次数 标记次数 函数
66 62 bond_vminfo_add+0x7c/0x200 [bonding]
109 0 memleak_max_object+0x3f7/0x7e0 [mem]
33 0 inet_bind_bucket_create+0x21/0x70
1 0 copy_fs_struct+0x22/0xb0
1 0 tracepoint_add_probe+0xf8/0x430
slab: kmalloc-64
object地址: 0xffff88003605e000
相似object数量: 593975
泄漏函数: bond_vminfo_add+0x7c/0x200 [bonding]