我正在编写一个应用程序,惊讶地发现它的总内存使用量已经太高了。 我想对我的应用程序进行动态内存使用分析:堆中有多少个各种类型的对象,以及创建这些对象的函数是哪些?此外,每个对象使用了多少内存?
有没有简单的方法可以做到这一点?我在Linux和Windows上都在工作,所以任何一个平台的工具都可以。
注意:我在这里不关心内存泄漏。
我正在编写一个应用程序,惊讶地发现它的总内存使用量已经太高了。 我想对我的应用程序进行动态内存使用分析:堆中有多少个各种类型的对象,以及创建这些对象的函数是哪些?此外,每个对象使用了多少内存?
有没有简单的方法可以做到这一点?我在Linux和Windows上都在工作,所以任何一个平台的工具都可以。
注意:我在这里不关心内存泄漏。
你有试过Valgrind吗?它是Linux的一款性能分析工具。它有一个内存检查器(用于检测内存泄露和其他内存问题)叫做Memcheck,还有一个堆分析器叫做Massif。
对于简单的统计,只需找出内存使用情况,您可以添加类似以下模板:
template<class T>
class Stats {
static int instance_count;
public:
Stats() {
instance_count++;
}
~Stats() {
instance_count--;
}
static void print() {
std::cout << instance_count << " instances of " << typeid(T).name() <<
", " << sizeof(T) << " bytes each." << std::endl;
}
};
template<class T>
int Stats<T>::instance_count = 0;
然后,您可以将其作为基类添加到您认为具有大量实例的类中,并打印出当前内存使用情况的统计信息:
class A : Stats<A> {
};
void print_stats() {
Stats<A>::print();
Stats<B>::print();
...
}
这并不会告诉你对象是在哪些函数中分配的,也不会提供太多细节,但它可能足以定位浪费内存的位置。
std::atomic
(如果您有C++11)或boost::atomic
来进行递增/递减操作。 - Alastair Maw对于Windows系统,请查看“crtdbg.h”中的函数。 crtdbg.h包含内存分配函数的调试版本。它还包含用于检测内存泄漏,损坏,检查堆指针有效性等的函数。
我认为以下函数对您很有用:
_CrtMemDumpStatistics _CrtMemDumpAllObjectsSince
以下MSDN链接列出了堆状态报告函数和示例代码 http://msdn.microsoft.com/en-us/library/wc28wkas(VS.80).aspx
MTuner - 一款免费的 C/C++ 内存分析器。以下是描述:
MTuner 是一个多平台的内存分析、泄漏检测和分析工具,支持 MSVC、GCC 和 Clang 编译器。其特点包括:基于时间线的内存活动历史记录、强大的过滤功能、用于手动插装的 SDK(带有完整源代码)、通过命令行使用的持续集成支持、内存泄漏检测等等。可对任何针对 GCC 或 Clang 交叉编译器的平台进行性能分析。内置支持 Windows、PlayStation 4 和 PlayStation 3 平台以及由基于 Windows 的交叉编译器针对的平台。
.MTuner
文件(约9GB)时,它也会崩溃。您是否尝试一次性将整个文件加载到内存中?您是否在代码中检查了内存分配失败的情况? - Amir Gonnen尝试使用gperftools - 它可以:
此外,它几乎不会影响程序效率。
有几件事情你可以做。最简单的方法是链接一个调试 malloc 库,根据你环境的细节(例如,在 Windows 上搜索 _malloc_dbg),有很多可供选择的库。
第二个选择是在 C++ 中重载 new 和 delete;你可以重载基本的 new 和 delete 函数,用新函数来跟踪内存分配和使用。
我刚刚发布了一个win32本地内存分析器MemPro,作为免费的测试版。 http://www.puredevsoftware.com/MemPro.htm。它钩入new/delete并将数据发送到外部应用程序,在那里您可以以各种不同的方式查看分配情况。希望这对您有所帮助。
第4.6章来自《游戏编程宝典8》(Safari图书预览链接),详细介绍了Ricky Lung开发的高级内存分析器,可以以层次化调用堆栈的方式显示分配统计信息,并支持多线程。