2009-05-26 84 views
42

我正在寻找一种方法来跟踪C++程序中的内存分配。我对不是感兴趣的内存泄漏,这似乎是大多数工具试图找到的东西,而是为应用程序创建内存使用情况配置文件。理想输出可以是一个大的函数名称列表,也可以是随着时间的推移分配的最大字节数,也可以是随时间变化的堆的图形表示。水平轴是时间,垂直轴堆空间。每个函数都会得到它自己的颜色,并根据分配的堆字节来绘制线条。用于标识分配的对象类型的奖励点也是如此。track C++内存分配

这个想法是找出内存瓶颈/可视化哪些功能/线程消耗最多的内存,应该作为进一步优化的目标。

我简要地看了一下Purify,BoundsChecker和AQTime,但他们似乎并不是我所追求的。 Valgrind看起来合适,但是,我在Windows上。 Memtrack看起来很有希望,但需要对源代码进行重大更改。

我的谷歌技能必须让我失败,因为它似乎并不是一个不寻常的要求?所有需要的信息来创建这样的工具应该可以从程序的调试符号和运行时API调用中随时获得 - 不是吗?

回答

7

Monitoring Your PC's Memory Usage For Game Development包含什么,我是一个近乎完美的例子寻找。它需要一段时间才能运行,但文章的作者非常有帮助。你可以在这里找到工具的源代码Memtracer

我还在SWENG(软件工程邮件列表)上得到了很多有用的答案。该线程被称为“[Sweng-Gamedev]监视C++内存使用情况?”。

27

使用Valgrind及其工具Massif。它的例子输出(的一部分):

99.48% (20,000B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc. 
->49.74% (10,000B) 0x804841A: main (example.c:20) 
| 
->39.79% (8,000B) 0x80483C2: g (example.c:5) 
| ->19.90% (4,000B) 0x80483E2: f (example.c:11) 
| | ->19.90% (4,000B) 0x8048431: main (example.c:23) 
| | 
| ->19.90% (4,000B) 0x8048436: main (example.c:25) 
| 
->09.95% (2,000B) 0x80483DA: f (example.c:10) 
    ->09.95% (2,000B) 0x8048431: main (example.c:23) 

所以,你会得到详细的信息:

  • WHO分配的内存(功能:克(),F(),和主()在上面的例子中);你也可以得到完整回溯导致分配功能,
  • 到数据结构的存储没有去(在上面的例子中没有数据结构),
  • 当它发生时,
  • 百分比是多少都分配内存的它是(G :39.7%,f:9.95%,主要:49.7%)。

这里是Massif manual

您可以跟踪堆分配以及堆栈分配(默认为关闭)。

PS。我刚刚读到你在Windows上。虽然我会留下答案,因为它给出了你可以从一个可能的工具中获得的图片。

+0

Massif不支持多核并且使程序变得太慢,有没有其他工具可以与多核一起工作? – ZRJ 2014-06-12 03:37:11

0

在Mac OS X上,您可以使用代码分析工具Shark来完成此操作,IIRC。

12

对于一个普通的C++内存跟踪器,您将需要重载以下几点:

global operator new 
global operator new [] 
global operator delete 
global operator delete [] 
any class allocators 
any in-place allocators 

棘手位越来越有用的信息,重载运营商只对分配器和内存指针删除大小信息。一个答案是使用宏。我知道。讨厌。新定义

void *operator new (size_t size, char *file, int line, char *function) 
{ 
    // add tracking code here... 
    return malloc (size); 
} 

以上仅适用,如果你没有任何运营商:发生在头是从所有的源文件包括 - 一个例子:

#undef new 

void *operator new (size_t size, char *file, int line, char *function); 
// other operators 

#define new new (__FILE__, __LINE__, __FUNCTION__) 

,并创建一个源文件在课堂范围内。如果你确实有一些在类的范围内,这样做:

#define NEW new (__FILE__, __LINE__, __FUNCTION__) 

并更换“新类型”与“新型”,但是这需要潜在地改变了很多代码。

由于这是一个宏,卸下内存跟踪器是相当简单的,标题变为:

#if defined ENABLED_MEMORY_TRACKER 
#undef new 

void *operator new (size_t size, char *file, int line, char *function); 
// other operators 

#define NEW new (__FILE__, __LINE__, __FUNCTION__) 
#else 
#define NEW new 
#endif 

和实现文件:

#if defined ENABLED_MEMORY_TRACKER 
void *operator new (size_t size, char *file, int line, char *function) 
{ 
    // add tracking code here... 
    return malloc (size); 
} 
endif 
0

在Xcode上,您可以使用Instruments来跟踪分配,虚拟机使用情况和其他几个参数。在iOS开发者中很受欢迎,但值得一试。

0

“随着时间的推移堆的图形表示” - 接近你正在寻找的是在Intel(R) Single Event API实施,详情可以在this article(其相当大的把它放在这里)找到。 Memory block allocations over time

它显示每个块大小的分配时间线,并允许添加额外的标记到您的代码,以更好地了解整个图片。