【问题标题】:How to Test for Memory Leaks?如何测试内存泄漏?
【发布时间】:2009-01-07 14:56:16
【问题描述】:

我们有一个包含数百个可能的用户操作的应用程序,并考虑如何增强内存泄漏测试。

目前的情况是这样的:在手动测试软件时,如果出现我们的应用程序消耗太多内存,我们使用内存工具,找出原因并修复它。这是一个相当缓慢且效率不高的过程:问题发现较晚,并且依赖于开发人员的善意。

我们如何改进?

  • 内部检查某些操作(如“关闭文件”)是否恢复了一些内存并记录下来?
  • 在我们的单元测试中断言内存状态(但这似乎是一项乏味的任务)?
  • 是否定期手动定期检查?
  • 每次实施新用户故事时都要检查吗?

【问题讨论】:

  • 您使用什么语言?它是像 Java 或 Perl 这样的垃圾收集语言,还是像 C 或 C++ 这样的非 GC 语言?
  • 什么平台?有可用的静态分析工具、内存分析工具和其他技术,但如果没有任何关于您的实现的细节,很难给您一个有用的答案。

标签: memory memory-leaks


【解决方案1】:

哪种语言?

我会使用 Valgrind 之类的工具,尝试完全运行程序并查看它报告的内容。

【讨论】:

    【解决方案2】:

    第一道防线:

    • 带有公共内存的检查列表 分配相关的错误 开发者
    • 编码指南

    第二道防线:

    • 代码审查
    • 静态代码分析(作为构建过程的一部分)
    • 内存分析工具

    如果您使用非托管语言(如 C/C++),您可以通过劫持内存管理函数有效地发现大部分内存泄漏。例如,您可以跟踪所有内存分配/释放。

    【讨论】:

      【解决方案3】:

      在我看来,问题的核心与其说是发现内存泄漏,不如说是知道何时测试它们。您说您有很多用户操作,但您没有说用户操作的序列 是有意义的。如果您可以随机生成有意义的序列,我会强烈反对随机测试。在随机测试中你会测量

      • 代码覆盖率(gcovvalgrind
      • 内存使用情况(valgrind
      • 用户操作本身的覆盖范围

      “覆盖用户操作”是指如下陈述:

      • 对于每对动作 A 和 B,如果存在有意义的动作序列,其中 A 紧跟 B,那么我们已经测试了这样的序列。

      如果不是这样,那么您可以询问 A 和 B 对中的哪一部分是正确的。

      如果您有足够的 CPU 周期来负担它,您可能还会受益于在每次提交到您的源代码存储库之前或在夜间构建期间运行 valgrind 或其他内存检查工具。

      自动化!

      【讨论】:

        【解决方案4】:

        在我的公司中,我们为我们的应用程序编写了一个无限的操作路径。 java 垃圾收集器应该清理所有未使用的映射和列表等。所以我们让应用程序从无尽的动作路径开始,看看内存使用大小是否在增长。

        检查哪些字段没有被删除可以使用JProfiler for Java。

        【讨论】:

          【解决方案5】:

          newdelete 替换为您的自定义版本,并记录每一个分配/解除分配的行为。

          一般来说(不是关于测试,而是从根源上解决问题),智能指针有助于避免这个问题。幸运的是,C++11 标准提供了新的便捷智能指针类(shared_ptrunique_ptr)。

          【讨论】:

            猜你喜欢
            • 2013-03-10
            • 1970-01-01
            • 2011-08-21
            • 1970-01-01
            • 2016-01-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多