如何测试内存泄漏?

6
我们有一个拥有数百个可能用户操作的应用程序,并考虑如何增强内存泄漏测试。
目前,我们的处理方式是:在手动测试软件时,如果发现我们的应用程序消耗了太多内存,我们使用内存工具找到原因并修复。这是一种相当缓慢且不高效的过程:问题被发现得很晚,而且依赖于一个开发人员的自觉性。
我们该如何改进呢?
- 内部检查某些操作(例如“关闭文件”)是否恢复了一些内存并记录下来? - 在我们的单元测试中断言内存状态(但似乎这将是一项繁琐的任务)? - 定期手动检查它? - 每次实现新用户故事时都包含该检查?

你正在使用什么编程语言?它是像Java或Perl这样的垃圾回收语言还是像C或C++这样的非GC语言? - j_random_hacker
而使用什麼平台呢?雖然有許多靜態分析工具、記憶體分析工具和其他技術可用,但如果沒有關於您的實現的具體信息,很難給出一個有用的答案。 - Patrick Cuff
5个回答

6

需要使用哪种语言?

我会使用类似Valgrind的工具,尽可能地运行程序并查看它报告了什么。


3

第一防线:

  • 为开发人员提供常见内存分配相关错误的检查清单
  • 编码指南

第二防线:

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

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


1

在我看来,问题的核心不是找到内存泄漏,而是知道何时测试它们。你说你有很多用户操作,但你没有说哪些用户操作序列是有意义的。如果你可以随机生成有意义的序列,我会强烈主张进行随机测试。在随机测试中,你将测量:

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

通过“用户操作的覆盖范围”,我指的是以下语句:

  • 对于每一对操作A和B,如果存在一个有意义的操作序列,在该序列中A紧接着B,则我们已经测试了这样的序列。

如果这不是真的,那么你可以询问有多少对A和B满足这个条件。

如果你有足够的CPU周期,运行valgrind或其他内存检查工具可能会对每次提交源代码到仓库之前或每晚构建都有好处。

自动化!


0

用你自己的版本替换newdelete,并记录每次分配/释放的操作。

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


0
在我们公司,我们为我们的应用程序编写了一个无尽的操作路径。Java垃圾收集器应该清理所有未使用的地图、列表等等。因此,我们让应用程序从无尽的操作路径开始,并查看内存使用大小是否增长。
您可以使用JProfiler for Java来检查哪些字段未被删除。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接