如何在源代码中查找内存泄漏

Posted

技术标签:

【中文标题】如何在源代码中查找内存泄漏【英文标题】:How to find memory leaks in source code 【发布时间】:2010-12-26 07:49:32 【问题描述】:

如果已知应用程序泄漏内存(在执行时),有哪些方法可以在应用程序的源代码中定位此类内存泄漏错误。 我知道可以在这里使用某些解析器/工具(可能对代码进行静态分析),但是还有其他方法/技术可以做到这一点,特定于语言(C/C++)/平台?

【问题讨论】:

你试过 Valgrind 吗? 我认为这是重复的:***.com/questions/1502799/…。我不确定您是在寻找运行时检测还是静态代码分析。 这是一道作业题吗?请提供您尝试调试的具体情况,或至少说明该程序正在执行的工作。 是的。有用于此目的的外部工具。但是是否有任何通用的编程指南来定位这些错误,特定于语言(C/C++)? 将代码浸入水中并注意气泡。 【参考方案1】:

Purify 会在这方面做得看起来很神奇

不仅是内存泄漏,还有许多其他类型的内存错误。

它通过实时检测您的机器代码来工作,因此您不需要源代码或使用任何特定选项进行编译。

只需使用 Purify 检测您的代码(执行此操作的最简单方法:CC="purify cc" make),运行您的程序,并获得一个漂亮的 gui 来显示您的泄漏和其他错误。

适用于 Windows、Linux 和各种风格的 Unix。提供免费试用下载。

http://www.ibm.com/software/awdtools/purify

【讨论】:

【参考方案2】:

就个人而言,我建议您使用clone_ptrclass 包装所有需要分配/解除分配内存的变量,该类在不再需要时为您执行所有内存解除分配。因此,您不必使用delete。它与auto_ptr 非常相似。主要区别在于您不必处理棘手的所有权转让部分。更多关于clone_ptr的信息和代码可以在here找到。

【讨论】:

【参考方案3】:

内存泄漏检测有两种通用技术,动态分析和静态分析。

在动态分析中,您运行代码,然后一个工具分析运行以查看最后泄漏了哪些内存。动态分析往往非常准确,但只会正确分析您在工具中执行的特定执行。因此,如果您的某些泄漏仅针对特定输入发生,并且您没有使用该输入的测试,则动态分析将无法检测到这些泄漏。

静态分析分析源代码以创建所有可能的代码路径,并查看其中任何一个是否可能发生泄漏。虽然静态分析现在非常好,但它并不完美 - 您不仅可以获得假阴性(分析遗漏泄漏),还可以获得假阳性(该工具声称您有泄漏,而实际上没有泄漏)。

有许多动态分析工具,包括众所周知的工具Valgrind(开源但仅限于 x86 Linux 和 Mac)和Purify(商业但也可用于 Windows、Solaris 和 AIX)。***也有一个不错的 some other dynamic analysis tools 列表。

在静态分析方面,我认为值得的唯一工具是Coverity(商业)。再一次,***有一个many other static analysis tools 的列表。

【讨论】:

【参考方案4】:

那里有 valgrind 和可能其他很棒的工具。 但我会告诉你我所做的,这对我来说非常有效,因为我多次在无法运行 valgrind 的环境中编写代码:

确保将每个分配与解除分配配对。我总是统计新闻或 malloc 并搜索删除或免费。 如果在 C++ 中并使用异常,请尝试将它们配对在构造函数/析构函数上。如果你喜欢冒险,或者不能把它们放在 Ctor/dtor 中,请确保没有异常可以使程序流不执行释放。 使用智能指针和 ptr 容器。 可以监控 alloc/dealloc 重写新或安装 malloc 处理程序。在某些时候,如果代码连续运行,很明显内存使用量是否会变得稳定并且不会无限制地增长,这将是最坏的泄漏情况。 小心使用永不收缩的容器,例如向量。有一些技巧可以缩小它们,将它们与空容器交换。

【讨论】:

最重要的成语:RAII (en.wikipedia.org/wiki/RAII)。它确保正确的资源释放。 在嵌入式环境中,漫不经心地把东西放在堆栈上并不是一件容易的事。而且通常你有很多静态数据,所以你不能总是做 RAII。并非所有东西都是钉子。【参考方案5】:

用于查找内存泄漏的通用指南并不多。幸运的是,防止大多数内存和其他资源的泄漏都有一个简单的指导方针:使用 RAII(资源获取即初始化),而且它们不会碰巧开始。这个名字是一个糟糕的描述,但如果你用谷歌搜索它,你应该会得到很多有用的结果。

【讨论】:

【参考方案6】:

您还可以使用 purify 来检测内存泄漏。

【讨论】:

【参考方案7】:
    使用 -g 标志编译您的代码 下载 valgrind(如果您在 Linux 上工作)并使用 --leak-check=yes 选项运行它

我认为 valgrind 是完成这项任务的最佳工具。

对于 Windows:请参阅此主题:Is there a good Valgrind substitute for Windows?

【讨论】:

【参考方案8】:

就手动操作而言,我认为没有任何既定做法。用细齿梳理代码,寻找news (allocs) 而没有对应的deletes (frees),就是这样。

【讨论】:

【参考方案9】:

如果您使用智能指针并保存它们的表格,那么您可以对其进行分析以判断您仍在使用哪些内存。提供一个窗口来查看它,或者更常见的是,在程序终止之前将其流式传输到日志。

【讨论】:

以上是关于如何在源代码中查找内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 valgrind 查找内存泄漏?

在 Chrome 开发工具中查找 JS 内存泄漏

如何自己检查NodeJS的代码是不是存在内存泄漏

如何防止java中的内存泄漏

如何查找我是不是有内存泄漏

如何使用 visualvm 查找内存泄漏