我有一个使用串行通信与外部设备交互的应用程序。 该设备有两个版本不同的实现。 – >一个由我的团队开发和testing – >另一个团队的另一个版本。 由于另一支队伍已经离队,我们的队伍正在维修。 在testing应用程序的前一天,我注意到应用程序在启动时占用了60Mb的内存,令人恐慌的是它的内存使用量开始以200Kb大小增长,在60小时内它增加到295Mb,尽pipe响应速度没有减慢和应用程序的使用。 我一次又一次地testing,并重复使用相同的内存使用模式。
该应用程序是在RHEL4上用C ++ Qt 4.2.1编写的。
我用mtrace来检查是否有内存泄漏,并且没有显示这样的泄漏。 然后我使用了valgrind memcheck工具,但是它给出的信息是神秘而不是非常确定的,它显示了Qt的graphics元素的泄漏,在审查时可以直接拒绝。
我正在修复哪些其他工具/方法可以用来查明这些内存泄漏的来源(如果有的话)。 – >另外,在更大的上下文中,我们如何检测和debuggingC ++ Qt应用程序中的内存泄漏? – >我们如何检查一个进程在Linux中使用多less内存?
我用gnome-system-monitor和top命令检查应用程序使用的内存,但是我听说上面提到的工具给出的结果不是绝对的。
编辑:
我用ccmalloc检测内存泄漏,这是closures应用程序后得到的错误报告。 在应用程序执行期间,没有错误消息。
| ccmalloc报告|
================================================== =====
| 总数| 分配| 释放| 垃圾|
+ ———– ————- + ————- + + ——— —- +
| 字节| 387325257 | 386229435 | 1095822 |
+ ———– ————- + ————- + + ——— —- +
|分配| 1232496 | 1201351 | 31145 |
+ ————————————————- —- +
| 检查次数:1
| 数量:2434332 |
| 检索地址的function名称…完成。 |
| 从gdb读取文件信息…完成。 |
| 按未收回的字节数进行sorting…完成。 |
| 呼叫链的数量:3 |
| 被忽略的呼叫链数量:0 |
| 报告的呼叫链数:3
| 内部呼叫链的数量:3 |
| 图书馆呼叫链的数量:1 |
================================================== =====
|
| 3.1%=在47次分配中分配的33.6 KB垃圾
| |
| | 0X ???????? 在
| |
| | 0x081ef2b6 in
| | 在src / wrapper.c:489
| |
| | 0x081ef169在<_realloc>中
| | 在src / wrapper.c:435
| |
| `—–> 0x081ef05c in
| 在src / wrapper.c:318
|
| 0.8%= 8722字节的垃圾分配在35个分配
| |
| | 0X ???????? 在
| |
| | 0x081ef134 in
| | 在src / wrapper.c:422
| |
| `—–> 0x081ef05c in
| 在src / wrapper.c:318
|
| 0.1%= 1144字节的垃圾分配在5个分配
| |
| | 0X ???????? 在
| |
| | 0x081ef1cb in
| | 在src / wrapper.c:455
| |
| `—–> 0x081ef05c in
| 在src / wrapper.c:318
|
`————————————————- —–
免费(0x09cb650c)报告后
(这可能发生在静态析构函数中。
当链接把`ccmalloc.o'放在末尾(对于gcc)或者
在目标文件列表的前面)。
报告后免费(0x09cb68f4)
报告后免费(0x09cb68a4)
报告后免费(0x09cb6834)
免费(0x09cb6814)报告后
报告后免费(0x09cb67a4)
免费(0x09cb6784)报告后
报告后免费(0x09cb66cc)
报告后免费(0x09cb66ac)
免费(0x09cb65e4)报告后
免费(0x09cb65c4)报告后
免费(0x09cb653c)报告后
ccmalloc_report()在非有效状态下调用
我不知道,这是什么意思,它似乎没有表明任何内存泄漏给我? 我可能是错的。 你们有没有遇到过这种情况? 链接|编辑|删除
如果你没有真正阅读手册或者其他文件,Valgrind可能是个婊子(初学者的手册页) – 但是它们是值得的。
基本上,你可以通过在你的应用程序中使用–gen-suppressions = all来运行valgrind,然后为源自QT本身的每个块创建一个抑制,然后使用抑制文件来阻止这些错误,你应该留下只有在你自己的代码中有错误。
另外,如果这样可以让事情变得更容易,你可以尝试使用valgrind通过一个alleyoop前端。
还有一些其他工具可以用来检测内存泄漏,Linux Journal在这里有文章: http : //www.linuxjournal.com/article/6556
最后,在某些情况下,一些静态分析工具也可以发现内存错误。
我想提出一个小问题,就是因为一个进程所使用的Meory越来越多,所以并没有出现内存泄漏。 以文字处理器为例 – 在写文本时,内存使用量增加了,但是没有泄漏。 实际上,大多数进程在运行时会增加它们的记忆用量,直到它们达到某种接近稳定的状态,在那里物体被创建时会被旧物体所破坏。
你说你尝试了Valgrind的memcheck
工具; 你还应该尝试一下massif
工具,它应该能够随时间绘制堆的使用情况,并告诉你从哪里分配内存。
测量内存使用量不是太有用的原因之一是,他们没有考虑到内存通常在进程之间共享。 为了最佳地了解进程分配内存的位置,我建议使用最新的Linux内核,并检查/proc/<pid>/maps
作为您的进程。 这显示了什么内存映射到该进程和从哪里。 例如,这里是我的系统上konqueror的一个片段。
b732a000-b7a20000 r-xp 00000000 fd:05 205437 /usr/lib/qt3/lib/libqt-mt.so.3.3.8 大小:7128 kB Rss:3456 kB Pss:347 kB 共享清理:3452 kB 共享脏:0 kB 私人清洁:4 kB 私人脏:0 kB 引用:3452 kB
这里最重要的是,虽然由于libqt-mt.so.3.3.8
的加载而产生的驻留集合是3456kB,但是所有加载该库的进程之间共享的却是4kB,所以这是一个一次性的系统全部成本。 top
不公开这个信息,所以从top
阅读RSS是误导性的。