对于系统程序来说,内存是在不断的分配和回收中被使用的。这是一个非常复杂的管理功能,在这个过程中,如果发生内存没有被及时回收的情况,那么就会造成内存的泄漏。
内存的泄露危害极大,应用程序没有及时回收的这部分内存,就无法再被系统分配,其他应用也无法使用。随着应用程序的使用,不被回收的内存会越积越多,直到占满整个内存空间,导致程序崩溃。虽然系统有OOM机制,但是在杀掉进程之前,系统整体性能都会出现问题,从而影响业务正常运行。
排查方法
要观察是否发生了内存泄露,我们首先可以使用一些基础命令来观察内存的使用变化情况。
用 top 或 ps 来观察进程的内存使用情况,然后找出内存使用一直增长的进程,最后再通过 pmap 查看进程的内存分布。
使用方法,已经在前面的几篇文章中讨论过。
再就是,可以通过vmstat来观察内存的变化情况。
# 每隔3秒输出一组数据
$ vmstat 3
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
00 06601824976201098784 0 0 0 0 623220010000
00 06601700976201098788 0 0 0 0 572510010000
00 06601320976201098788 0 0 0 3 523060010000
00 06601452976281098788 0 0 0 27 633260010000
20 06601328976281098788 0 0 0 44 522990010000
00 06601080976281098792 0 0 0 0 562850010000
除了这些基础的工具来初步判断外,今天重点推荐一个工具memleak,快速的分析出内存泄露的位置。
memleak 可以跟踪系统或指定进程的内存分配、释放请求,然后定期输出一个未释放内存和相应调用栈的汇总情况。
memleak -p
常用参数
-p :附加到指定进程 ID 的进程。
-a:跟踪所有内存分配(包括已释放的)。
-o :将输出写入文件。
-s :只显示分配大小大于等于 的内存泄漏。
-i :单位s,设置统计间隔
例如:
# 实时监控并保存到文件
sudo memleak -p <PID> -o | tee memory_leak.log
# 使用watch持续监控
watch -n 10"sudo memleak -p <PID> -c 20"
#输出
[12:34:56] Top 10 stacks with outstanding allocations:
128 bytes in4 allocations from stack
malloc+0x1a [libc]
create_object+0x25 [myapp]
process_request+0x67 [myapp]
512 bytes in2 allocations from stack
calloc+0x15 [libc]
init_buffer+0x3e [myapp]
944

被折叠的 条评论
为什么被折叠?



