如何追捕瓦尔格林德说不存在的内存泄漏?

how to hunt down memory leak valgrind says doesn't exist?

本文关键字:不存在 林德 内存 泄漏 何追捕 追捕      更新时间:2023-10-16

我有一个程序,它接受来自套接字的数据,对其进行一些质量控制和各种其他条件处理,然后将其写入一个命名管道。我在上面运行了valgrind,修复了最初存在的所有内存泄漏。然后,我在一个系统上创建了一个"演示"环境,我有32个运行该程序的实例,每个实例都被提供了唯一的数据,并且每个实例都输出到自己的管道中。我们测试了一下,一切看起来都很好。然后我试着通过将数据发送速度提高到荒谬的速度来进行压力测试,起初情况看起来不错。。。但我的程序不断消耗越来越多的内存,直到我没有资源了。

我转向valgrind并运行完全相同的设置,只是每个程序都在valgrind内部运行,使用泄漏检查=满。发生了一些奇怪的事情。首先,内存确实泄漏了,但只是到了每个程序消耗了我.9%内存的程度(以前最大的内存占用者占了我6%的内存)。随着valgrind的运行,程序的CPU成本飙升,而我现在的CPU是100%,平均负载很大,所以可能是由于缺乏可用的CPU,导致程序运行得足够慢,以至于泄漏花了太长时间才显现出来。当我尝试停止这些程序时,valgrind没有显示出直接的内存泄漏,它显示出一些潜在的内存泄露,但我检查了它们,我不认为它们中的任何一个代表真正的内存泄漏;此外,当程序消耗超过100MB时,可能的内存泄漏仅显示为几千字节。valgrind报告的可访问(未泄漏)内存也在KB范围内,因此valgrind似乎认为我的程序消耗的内存只是Top所说的内存的一小部分。

我还做了一些其他的测试,结果很奇怪。一个程序,即使以我最初检测到的内存泄漏速度的三倍运行,似乎也不会消耗超过.9%的内存,两个程序分别泄漏了1.9%和1.3%的内存,但没有更多等等,就好像泄漏的内存量和泄漏的速度在某种程度上取决于我的程序一次运行的实例数量;这毫无意义,每个实例都应该100%独立于其他实例。

我还发现,如果我运行32个实例,而只有一个实例在valgrind中运行,那么valgrind实例(如果我说是的话,那就是一个词!)会泄漏内存,但速度比在valgriund之外运行的实例慢。valgrind实例仍然会说我没有直接泄漏,并且报告的内存消耗比Top显示的要少得多。

我很困惑是什么导致了这个结果,以及为什么valgrind拒绝意识到内存泄漏。我以为它可能是一个外部图书馆,但我并没有真正使用任何外部图书馆;只是基本的C++函数/对象。我还认为,可能是写入输出管道的数据过快导致缓冲区无限期增长,但1)这种缓冲区应该有一个增长的上限;2)一旦内存泄漏,如果我将数据输入率降至零,内存就会保持消耗,而不是缓慢地降回合理的数量。

有人能给我一个提示,告诉我从这里应该往哪里看吗?我完全不明白为什么记忆会这样。

谢谢。

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

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

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

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

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

我可以建议您试用MemoryCape吗?这个工具在内存泄漏检测方面做得很好。它不是免费的,但考虑到花费的时间和精力,它值得一试。