如何追捕内存泄漏valgrind说不存在?

时间:2012-08-30 15:46:19

标签: c++ memory-leaks valgrind memory-leak-detector

我有一个程序接受来自套接字的数据,进行一些质量控制并对其进行各种调整,然后将其写入命名管道。我在上面运行valgrind并修复了最初存在的所有内存泄漏。然后我在一个系统上创建了一个'demo'环境,在这个系统中我运行了32个这个程序的实例,每个实例都输入了唯一的数据,每个数据输出到它自己的管道。我们对它进行了测试,一切看起来都很好。然后我尝试通过提高数据发送速率到荒谬的速度进行压力测试,事情看起来很好......但是我的程序在没有资源的情况下继续消耗越来越多的内存。

我转向valgrind并运行完全相同的设置,除了使用leak-check = full在valgrind中运行的每个程序。发生了一些奇怪的事情。首先,内存确实泄漏了,但只是到了每个程序耗尽的程度。我的内存占了9%(之前最大的内存占了我内存的6%)。随着valgrind运行程序的CPU成本上升,我现在处于100%cpu且负载平均值很高,因此缺少可用的CPU可能导致程序运行缓慢,泄漏时间太长而无法显示。当我尝试停止这些程序时,valgrind显示没有直接的内存泄漏,它显示了一些潜在的内存泄漏,但我检查了它们,我不认为它们中的任何一个代表真正的内存泄漏;此外,当程序消耗超过100 MB时,可能的内存泄漏仅显示为几千字节。 valgrind报告的可到达(非泄漏)内存也在KB范围内,因此valgrind似乎相信我的程序占用了Top所说的内存的一小部分。

我已经进行了一些其他测试并获得了奇怪的结果。一个程序,甚至以我检测到的原始内存泄漏速率的三倍运行,似乎从不消耗超过0.9%的内存,两个程序分别泄漏到1.9和1.3%的内存,但没有更多等等,这就像是泄漏的内存量和泄漏的速率在某种程度上取决于我的程序一次运行多少个实例;这没有任何意义,每个实例应该100%独立于其他实例。

我还发现如果我运行32个实例,只有一个实例在valgrind中运行valgrinded实例(如果我说它是一个单词!)泄漏内存,但速度比在valgrind之外运行的速度慢。 valgrind实例仍然会说我没有直接泄漏,报告的内存消耗远低于Top显示。

我对于导致这个结果的原因感到很难过,为什么valgrind拒绝意识到内存泄漏。我认为它可能是一个外部库,但我并没有真正使用任何外部库;只是基本的C ++函数/对象。我还认为它可能是写入输出管道的数据快速导致缓冲区无限增长,但1)应该有一个上限,这样的缓冲区可以增长和2)一旦内存泄漏,如果我删除数据输入率到内存不会消耗,而是慢慢回落到合理的数量。

任何人都可以给我一个关于我应该从哪里看的提示吗?我完全不知道为什么记忆就是这样的。

感谢。

3 个答案:

答案 0 :(得分:2)

首先应该寻找软泄漏。当某些静态或单个逐渐增加某些缓冲区或容器并将垃圾收集到其中时,就会发生这种情况。从技术上讲,它不是泄漏,但其效果一样糟糕。

答案 1 :(得分:2)

我建议您尝试使用MemoryScape吗?这个工具在内存泄漏检测方面做得非常好。这不是免费的,但考虑到花费的时间和精力,值得尝试。

答案 2 :(得分:2)

这听起来像是我最近遇到的一个问题。

如果你的程序接受数据并在内部缓冲它而没有任何限制,那么它的读取和缓冲速度可能比输出数据的速度快。在这种情况下,内存使用将继续无限制地增加。

您运行的程序的实例越多,每个实例的速度就越慢,缓冲区的增加速度就越快。

这可能是您的问题,也可能不是,但没有更多信息,这是我能做的最好的事情。