4

I have a Windows application written using C++ using Visual Studio 2008. I want to obtain statistics on memory usage to find bottlenecks and locations to work on memory usage. Ideally I'd like to have a tool that does this without having to go in and add counter/profiling logic to the code itself. Basically what I'm looking for is:

  • List of all allocations (freed or not shouldn't matter, I want to know every time something is allocated)
  • Callstack of each allocation and a counter representing the number of times that code was called and memory was allocated.
  • Information on what memory has been freed vs not freed (to find leaks). Ideally it would be intelligent enough to determine if memory is still in use or if it really has leaked (via scope, or some other intelligent mechanism).

I don't care if it's a free tool or not. Here are some tools I've already looked at:

  • Rational PurifyPlus: Honestly I haven't been able to make much use of this tool. It returns a lot of false positives. Also, it doesn't give me the first 2 items in my list above, it instead seems to only focus on memory errors and leaks.
  • Sysinternals VMMap: This tool is interesting and allows me to see how memory is spread out (stack vs heap vs shared heap, etc). It also lets me see a call tree of allocations but isn't very intuitive or helpful. It's hard to make sense out of the data.
  • DevPartner Boundschecker: I really think this is the most useless tool so far. I used it years ago before they got bought out by DevPartner and I remember it working a lot better. But it doesn't really give me the statistical data I need, nor does it seem to be able to properly detect memory leaks.

I appreciate in advance any help / advice. My application is a server, and suffers serious memory growth issues over time during stress testing (and eventually crashes due to virtual bytes exceeding the limit for 32-bit applications). Having the right tool will help me isolate where we are allocating memory and also where we might be leaking memory.

Kara
  • 6,115
  • 16
  • 50
  • 57
void.pointer
  • 24,859
  • 31
  • 132
  • 243
  • Is is possible for you to compile your code on Linux, or it would be too big of a problem ? BTW if you allocate a lot of your own classes you could use CRTP to count and log number of alive instances: http://stackoverflow.com/questions/7097679/simplest-way-to-count-instances-of-an-object – NoSenseEtAl Aug 28 '12 at 20:56

5 Answers5

2

Could you modify your code to use the debug version of malloc, realloc and free? If yes, check _malloc_dbg, _realloc_dbg and _free_dbg.

(You could write own new and delete operators based on these functions.)

#ifdef _DEBUG
# define _CRTDBG_MAP_ALLOC 1
# include <Crtdbg.h>
# define malloc(size)       _malloc_dbg(size,_CLIENT_BLOCK,__FILE__,__LINE__)
# define realloc(addr,size) _realloc_dbg(addr,size,_CLIENT_BLOCK,__FILE__,__LINE__)
# define free(addr)         _free_dbg(addr,_CLIENT_BLOCK)
void * operator new ( size_t size, const char * filename, int linenumber )
{
  void * addr = _malloc_dbg( size, _CLIENT_BLOCK, filename, linenumber );
  if ( addr == 0 )
    throw std::bad_alloc;
  return addr;
}
void * operator new ( size_t size, const std::nothrow_t &no_throw, const char * filename, int linenumber )
{
  return _malloc_dbg( size, _CLIENT_BLOCK, filename, linenumber );
}
void * operator new [] ( size_t size, const char * filename, int linenumber )
{
  void * addr = _malloc_dbg( size, _CLIENT_BLOCK, filename, linenumber );
  if ( addr == 0 )
    throw std::bad_alloc;
  return addr;
}
void * operator new [] ( size_t size, const std::nothrow_t &no_throw, const char * filename, int linenumber )
{
  return _malloc_dbg( size, _CLIENT_BLOCK, filename, linenumber );
}
void operator delete( void *p, const char * filename, int linenumber )
{
  _free_dbg(p,_CLIENT_BLOCK);
}
void operator delete [] ( void *p, const char * filename, int linenumber )
{
  _free_dbg(p,_CLIENT_BLOCK);
}
# define DEBUG_NEW_HEAP new( __FILE__, __LINE__ )
# define new DEBUG_NEW_HEAP
#endif

(Ref.: prev. topic)

Community
  • 1
  • 1
Naszta
  • 7,560
  • 2
  • 33
  • 49
2

At my work location, we use Software Verification's Memory Validator. It will give you various memory statistics, lists of allocations, call stack of each allocation, and memory leaks. It has proven to be occasionally useful in my work experience.

StarPilot
  • 2,246
  • 1
  • 16
  • 18
  • Interesting option but I could never get an evaluation license, so I was never able to test this tool. – eri0o Dec 16 '22 at 19:33
0

The CRT memory debugging features in Visual Studio go a long way. The extra stuff you want requires logging each allocation. The CRT offers _CrtSetAllocHook for just this kind of thing.

Adrian McCarthy
  • 45,555
  • 16
  • 123
  • 175
  • Will this capture allocations from third party DLLs as well? I happen to have debug DLLs of my third party libraries. I've thought of overloading global new & delete to capture information, but this wouldn't extend into my third party debug DLLs AFAIK. – void.pointer Aug 28 '12 at 21:43
  • Overloading new and delete is generally troublesome, especially when using DLLs outside your control. The CRT alloc hook is very low level. If all the DLLs realy on the DLL version of the run-time, you should be in good shape, as long as you can set the hook before the DLLs do a bunch of allocations. If one or more of the DLLs are linked against the static CRT, then you probably won't be able to track those allocations. – Adrian McCarthy Aug 28 '12 at 22:02
-1

You could give Valgrind a try.

Rapptz
  • 20,807
  • 5
  • 72
  • 86
-1

If you have not seen this already you may wish to look here. It appears to have been quite recently updated.

Sysinternals Suite By Mark Russinovich http://technet.microsoft.com/en-us/sysinternals/bb842062.aspx

Mark Rovetta
  • 691
  • 6
  • 16
  • In my original question I mentioned that I have tried VMMap which is the only tool in the suite I'm aware of that will even remotely help me with what I need. – void.pointer Aug 28 '12 at 21:47