我们有一个包含数百个可能的用户操作的应用程序,并考虑如何增强内存泄漏测试。
目前,它的发生方式是这样的:在手动测试软件时,如果出现我们的应用程序消耗太多内存,我们使用内存工具,查找原因并修复它。这是一个相当缓慢且效率不高的过程:问题发现较晚,并且依赖于开发人员的善意。
我们该如何改进呢?
- 在内部检查某些操作(例如“关闭文件”)是否恢复了一些内存并记录下来?
- 在我们的单元测试中断言内存状态(但这似乎是一项乏味的任务)?
- 不定期手动定期检查?
- 每次实施新的用户故事时都包括该检查吗?
我们有一个包含数百个可能的用户操作的应用程序,并考虑如何增强内存泄漏测试。
目前,它的发生方式是这样的:在手动测试软件时,如果出现我们的应用程序消耗太多内存,我们使用内存工具,查找原因并修复它。这是一个相当缓慢且效率不高的过程:问题发现较晚,并且依赖于开发人员的善意。
我们该如何改进呢?
哪种语言?
我会使用 Valgrind 之类的工具,尝试完全运行程序并查看它报告的内容。
第一道防线:
第二道防线:
如果您使用非托管语言(如 C/C++),您可以通过劫持内存管理函数有效地发现大部分内存泄漏。例如,您可以跟踪所有内存分配/释放。
在我看来,问题的核心与其说是发现内存泄漏,不如说是知道何时测试它们。你说你有很多用户操作,但你没有说什么用户操作序列是有意义的。如果您可以随机生成有意义的序列,我会强烈反对随机测试。在随机测试中,您将测量
“覆盖用户操作”是指如下陈述:
如果这不是真的,那么您可以询问 A 和 B 对中的哪一部分是正确的。
如果您有足够的 CPU 周期来负担它,那么在每次提交到源代码存储库之前或在夜间构建期间,您可能还会从运行valgrind
或其他内存检查工具中受益。
自动化!
在我的公司,我们为我们的应用程序编写了一个无穷无尽的操作路径。java 垃圾收集器应该清理所有未使用的映射和列表之类的东西。所以我们让应用程序从无尽的动作路径开始,看看内存使用大小是否在增长。
检查哪些字段没有被删除,您可以使用 JProfiler for Java。
用您的自定义版本替换new和delete并记录分配/解除分配的每一个行为。
一般来说(不是关于测试,而是从根源上解决问题),智能指针有助于避免这个问题。幸运的是,C++11 标准提供了新的方便的智能指针类(shared_ptr
, unique_ptr
)。