跟踪 C++ 内存分配

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/910172/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 17:55:05  来源:igfitidea点击:

track C++ memory allocations

c++windowsmemory-managementvisualization

提问by BuschnicK

I am looking for a way to track memory allocations in a C++ program. I am notinterested in memory leaks, which seem to be what most tools are trying to find, but rather creating a memory usage profile for the application. Ideal output would be either a big list of function names plus number of maximum allocated bytes over time or better yet, a graphical representation of the heap over time. Horizontal axis is time, vertical axis heap space. Every function would get it's own color and draw lines according to allocated heap bytes. Bonus points for identifying allocated object types as well.

我正在寻找一种在 C++ 程序中跟踪内存分配的方法。我对内存泄漏感兴趣,这似乎是大多数工具试图找到的,而是为应用程序创建内存使用配置文件。理想的输出要么是一个大的函数名称列表加上随时间推移的最大分配字节数,要么更好,随时间推移的堆的图形表示。横轴是时间,纵轴是堆空间。每个函数都会根据分配的堆字节获得自己的颜色并绘制线条。识别分配的对象类型也有奖励积分。

The idea is to find memory bottlenecks/to visualize what functions/threads consume the most memory and should be targetted for further optimization.

这个想法是找到内存瓶颈/可视化哪些函数/线程消耗最多的内存并且应该作为进一步优化的目标。

I have briefly looked at Purify, BoundsChecker and AQTime but they don't seem to be what I'm after. Valgrind looks suitable, however, I'm on Windows. Memtracklooks promising, but requires significant changes to the source code.

我曾简要地研究过 Purify、BoundsChecker 和 AQTime,但它们似乎不是我所追求的。Valgrind 看起来很合适,但是,我使用的是 Windows。Memtrack看起来很有希望,但需要对源代码进行重大更改。

My google skills must have failed me, cause it doesn't seem to be such an uncommon request? All the needed information to create a tool like that should be readily available from the program's debug symbols plus runtime API calls - no?

我的谷歌技能一定让我失败了,因为这似乎不是一个不常见的要求?创建这样的工具所需的所有信息都应该可以从程序的调试符号和运行时 API 调用中轻松获得——不是吗?

回答by BuschnicK

Use Valgrind and its tool Massif. Its example output (a part of it):

使用 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)

So, you will get detailed information:

因此,您将获得详细信息:

  • WHO allocated the memory (functions: g(), f(), and main() in above example); you also get complete backtrace leading to allocating function,
  • to WHICH data structure the memory did go (no data structures in above example),
  • WHEN it happened,
  • what PERCENTAGE of all allocated memory it is (g: 39.7%, f: 9.95%, main: 49.7%).
  • WHO 分配了内存(函数:上例中的 g()、f() 和 main());您还可以获得导致分配功能的完整回溯,
  • 内存确实去了哪个数据结构(上例中没有数据结构),
  • 发生的那一刻,
  • 它是所有分配内存的百分比(g:39.7%,f:9.95%,main:49.7%)。

Here is Massif manual

这是Massif 手册

You can track heap allocation as well as stack allocation (turned off by default).

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

PS. I just read that you're on Windows. I will leave the answer though, because it gives a picture of what you can get from a possible tool.

附注。我刚刚读到您使用的是 Windows。不过,我会留下答案,因为它给出了您可以从可能的工具中获得什么的图片。

回答by Nitin Bhide

Microsoft have well documented memory tracking functions. However, for some reason they are not really well-known in the developer community. These are CRT debug functions. Good starting point will be CRT Debug Heap functions.

Microsoft 有详细记录的内存跟踪功能。但是,出于某种原因,它们在开发人员社区中并不是很出名。这些是 CRT 调试功能。好的起点将是CRT 调试堆函数

Check the following links for more details

查看以下链接了解更多详情

  1. Heap state reporting functions
  2. Tracking heap allocation requests. Probably this is the functionality that you are looking for.
  1. 堆状态报告函数
  2. 跟踪堆分配请求。可能这就是您正在寻找的功能。

回答by Skizz

For a generic C++ memory tracker you will need to overload the following:

对于通用 C++ 内存跟踪器,您需要重载以下内容:

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

The tricky bit is getting useful information, the overloaded operators only have size information for allocators and memory pointers for deletes. One answer is to use macros. I know. Nasty. An example - place in a header which is included from all source files:

棘手的一点是获取有用的信息,重载的运算符只有分配器的大小信息和删除的内存指针。一种答案是使用宏。我知道。可恶的。一个示例 - 放置在所有源文件中包含的标题中:

#undef new

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

#define new new (__FILE__, __LINE__, __FUNCTION__)

and create a source file with:

并创建一个源文件:

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

The above only works if you don't have any operator new defined at class scope. If you do have some at class scope, do:

仅当您没有在类范围内定义任何运算符 new 时,上述内容才有效。如果您确实在课堂范围内有一些,请执行以下操作:

#define NEW new (__FILE__, __LINE__, __FUNCTION__)

and replace 'new type' with 'NEW type', but that requires changing a lot of code potentially.

并将“新类型”替换为“新类型”,但这可能需要更改大量代码。

As it's a macro, removing the memory tracker is quite straightforward, the header becomes:

由于它是一个宏,因此删除内存跟踪器非常简单,标题变为:

#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

and the implementation file:

和实现文件:

#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

回答by Totoro

On Xcode, you can use Instruments to track allocations, VM usage, and several other parameters. Mostly popular among iOS developers, but worth a try.

在 Xcode 上,您可以使用 Instruments 来跟踪分配、VM 使用情况和其他几个参数。最受 iOS 开发人员欢迎,但值得一试。

回答by araud

"A graphical representation of the heap over time" - close to what you are looking for is implemented in Intel(R) Single Event API, details can be found in this article(its rather big to put it here). Memory block allocations over time

“随时间推移的堆图形表示” - 接近您正在寻找的内容是在Intel(R) Single Event API 中实现的,详细信息可以在这篇文章中找到(把它放在这里相当大)。随着时间的推移内存块分配

It shows you timeline of per-block-size allocations and allows to add additional mark up to your code to understand the whole picture better.

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

回答by gavinb

The Visual Studio IDE has built-in heap profiling support (since 2015), which is probably the easiest to start with. It has graphical views of heap usage over time, and can track allocations by function/method.

Visual Studio IDE 具有内置的堆分析支持(自 2015 年起),这可能是最容易开始的。它具有随时间推移的堆使用情况的图形视图,并且可以通过函数/方法跟踪分配。

heap profiling

堆分析

The CRT also has debug and profile support, which is more detailed and more low-level. You could track the data and plot the results using some other tool:

CRT 还具有调试和配置文件支持,这些支持更详细、更底层。您可以使用其他一些工具跟踪数据并绘制结果:

In particular, look at _CrtMemCheckpointand related functions.

特别是看_CrtMemCheckpoint和相关的函数。

回答by paxos1977

On Mac OS X, you can use the code profiling tool Shark to do this, IIRC.

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