【发布时间】:2017-07-07 20:54:15
【问题描述】:
这是 Linux 的平台相关问题。如果这很重要,我特意询问的是 C++11 之前的版本。
我想通过new 和delete 间接测试一个类的析构函数,看看程序堆上的所有内存是否都被释放,这可以检查内存泄漏。
object* x; //pointer allocated on the stack
... //measure available heap space
x = new object(); //allocated on the heap
delete x; //deallocate that heap space
... //measure again, see if it's the same
我知道 Valgrind 有 Massif(……有 Massif 的 C++ 库吗……?),我什至可以对我的整个程序运行内存泄漏检查,但代码会发生变化。单元测试很重要,我无法对所有代码进行完全单元测试,这让我烦死。
我可以编写什么代码来测量可用堆空间?
【问题讨论】:
-
我会说这是错误的方法——“available”堆空间随着时间的推移并不是一个常数。映射到您的进程的内存将发生变化,因为分配器会调用操作系统特定的 API,例如
sbrk()和mmap()。那么什么是“可用”?只有当前映射到您的流程的内容?或者你的进程可能被映射的所有内存?后者更加复杂(linux overcommits,顺便说一句)。另一种方法可以工作(但当然取决于实现):测量已用堆空间的数量。 -
总而言之,您可能会“更快乐”地做其他人所做的事情:对您的实际业务逻辑使用单元测试,并定期使用
valgrind之类的工具查找内存处理错误(调用它是一个集成测试) ;) -
典型的解决方案是使用ASAN (address sanitizer) 或您自己说的在valgrind 下运行单元测试。我不确定你为什么要从程序中测量它。只需运行一个创建和删除对象的单元测试,然后告诉您的测试驱动程序在 valgrind 下运行该测试。
-
如果您希望能够在不运行在单独的调试环境中的情况下跟踪堆使用情况(即,无论出于何种原因,您不喜欢在 valgrind 下运行),您可以重载 C++ 的 new 和 delete 运算符跟踪和报告您的程序在任何给定时间分配了多少字节的内存。一个例子在这里:almostinfinite.com/memtrack.html
标签: c++ linux unit-testing memory-leaks heap-memory