Answers:
找出导致内存泄漏的进程的PID。
ps -aux
捕获/proc/PID/smaps
并保存到类似的文件中BeforeMemInc.txt
。
/proc/PID/smaps
并保存afterMemInc.txt
找到first smaps
和2nd 之间的差异smaps
,例如
diff -u beforeMemInc.txt afterMemInc.txt
记下增加内存的地址范围,例如:
beforeMemInc.txt afterMemInc.txt
---------------------------------------------------
2b3289290000-2b3289343000 2b3289290000-2b3289343000 #ADDRESS
Shared_Clean: 0 kB Shared_Clean: 0 kB
Shared_Dirty: 0 kB Shared_Dirty: 0 kB
Private_Clean: 0 kB Private_Clean: 0 kB
Private_Dirty: 28 kB Private_Dirty: 36 kB
Referenced: 28 kB Referenced: 36 kB
Anonymous: 28 kB Anonymous: 36 kB #INCREASE MEM
AnonHugePages: 0 kB AnonHugePages: 0 kB
Swap: 0 kB Swap: 0 kB
KernelPageSize: 4 kB KernelPageSize: 4 kB
MMUPageSize: 4 kB MMUPageSize: 4 kB
Locked: 0 kB Locked: 0 kB
VmFlags: rd wr mr mw me ac VmFlags: rd wr mr mw me ac
使用GDB在正在运行的进程上转储内存或使用以下命令获取coredump gcore -o process
我在运行过程中使用gdb将内存转储到某些文件。
gdb -p PID
dump memory ./dump_outputfile.dump 0x2b3289290000 0x2b3289343000
现在,使用strings
命令或hexdump -C
打印dump_outputfile.dump
strings outputfile.dump
您将获得可读的表格,可以在其中将这些字符串定位到源代码中。
分析您的来源以查找泄漏。
我认为memleax正是您想要的。
它通过附加运行中的进程来调试其内存泄漏,而无需重新编译程序或重新启动目标进程。非常方便,适合生产环境。
它适用于GNU / Linux和FreeBSD。
注意:我是作者,欢迎任何建议
==编辑==
我写了另一个工具libleak,它通过LD_PRELOAD挂钩内存功能。
也无需修改目标程序。尽管必须使用LD_PRELOAD重新启动进度,但是可以在运行期间启用/禁用检测。
由于没有信号陷阱,因此对性能的影响要小得多。
与类似的工具(例如mtrace)相比,它在可疑的内存泄漏点打印完整的调用堆栈。
在Linux上,可以在程序中启用mtrace,但这是代码更改。
在OpenBSD上,您可以尝试使用malloc stats。
Google的泄漏检查程序也可能值得一看,与mtrace不同,您可以使用它LD_PRELOAD
来避免重新编译。
我认为,在直接在源代码中启动程序后,如果不提供对分配监视的支持,那么您很不幸。我可以想到以下两个原因:
但是,如果您的程序在虚拟机中运行,则该环境可能会提供监视分配的支持。我知道Java有几个分配和垃圾收集监视工具(例如visualVM),它们附接到正在运行的程序或VM。