应用开发过程,出现内存泄露一般的都可以使用第三方工具valgrind进行检查,确认内存泄露的点,但是内核的内存泄漏又是怎么解决呢?下面一起来看一下。
如何判定内核有内存泄漏?
内存泄漏,是系统可用内存持续的减少。系统运行阶段肯定会存在一定的波动,但是只要不是已使用内存持续增长的,都不算内存泄漏,而在系统层面,可以通过/proc/meminfo
这个节点查看当前的系统内存信息。
root@Linux:/# cat /proc/meminfo
MemTotal: 239212 kB //当前系统可使用的物理内存
MemFree: 157576 kB //系统空闲内存
MemAvailable: 176488 kB //MemFree+Buffers+Cached约等MemAvailable,该值为估值
Buffers: 5288 kB //表示块设备(block device)所占用的缓存页
Cached: 16316 kB //Page Cache里包括所有file-backed pages,Cached是”Mapped”的超集,就是说它不仅包括mapped,也包括unmapped的页面
SwapCached: 0 kB //系统中有多少匿名页曾经被swap-out、现在又被swap-in并且swap-in之后页面中的内容一直没发生变化
Active: 11288 kB //活动内存,Active = Active(anon) + Active(file)
Inactive: 11832 kB //非活动内存,Inactive = Inactive(anon) + Inactive(file)
Active(anon): 1524 kB //与文件无关的内存(比如进程的堆栈,用malloc申请的内存)
Inactive(anon): 16 kB
Active(file): 9764 kB //与文件关联的内存(比如程序文件、数据文件所对应的内存页)
Inactive(file): 11816 kB
Unevictable: 0 kB
Mlocked: 0 kB //统计的是被mlock()系统调用锁定的内存大小
SwapTotal: 0 kB
SwapFree: 0 kB
Dirty: 0 kB
Writeback: 0 kB
AnonPages: 1592 kB //Anonymous pages(匿名页)的数量统计,Anonymous Pages是与用户进程共存的,一旦进程退出,则Anonymous pages也释放
Mapped: 2484 kB //用户进程的file-backed pages
Shmem: 24 kB //Shmem = shard memory + tmpfs + devtmpfs
Slab: 12580 kB //Slab = SReclaimable+SUnreclaim
SReclaimable: 3372 kB //slab中可回收部分,调用kmem_getpages()时加上SLAB_RECLAIM_ACCOUNT标记,表明是可回收的
SUnreclaim: 9208 kB //slab中不可回收部分
KernelStack: 1232 kB //每个用户线程都会分配一个kernel stack,该部分用户态代码不可访问
PageTables: 208 kB //Page Table用于将内存的虚拟地址翻译成物理地址,随着内存地址分配得越多,Page Table随之增大
NFS_Unstable: 0 kB //不稳定页表的大小
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 119604 kB
Committed_AS: 44660 kB
VmallocTotal: 263061440 kB //vmalloc内存区大小
VmallocUsed: 1196 kB //已使用的vmalloc区大小
VmallocChunk: 0 kB
CmaTotal: 81920 kB //cma大小
CmaFree: 40888 kB
通过上面的信息,我们可以了解到当前系统的内存使用情况。当怀疑系统存在内存泄漏时,可通过一段时间内持续的查看/proc/meminfo
中的内容信息,如果发现随着时间增长,slab或VmallocUsed一直增大,则说明slab泄漏或vmalloc泄漏。
内核内存泄露排查可查看内核检查内存泄漏的工具 — kmemleak、slub debug。