4

I have a problem with an application I'm debugging. Steady state memory usage is a few hundred megabytes. Occasionally (after several hours) it gets into a state where its memory usage soars to many gigabytes. I would like to be able to stop the program as soon as memory usage this happens.

Where control passes through my own code, I can trap excessive memory use with code like this:

bool usingTooMuchMemory()
{
    PROCESS_MEMORY_COUNTERS pmc;
    if (GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof pmc))
        return pmc.WorkingSetSize > 0x80000000u; // 2GB working set
    return false;
}

This doesn't help me because I need to test working set size at the right point. I really want the program to break on the first malloc or new that takes either working set or heap size over some threshold. And ideally I'd like to have this done by the CRT heap itself with minimal overhead because the library likes to allocate huge numbers of small blocks.

The suspect code is in a DLL running in a thread created by my calling code. The DLL links statically to the CRT and has no special heap management. I have source code for the DLL.

Any ideas? Am I missing something obvious?

trincot
  • 317,000
  • 35
  • 244
  • 286
paperjam
  • 8,321
  • 12
  • 53
  • 79

3 Answers3

4

You can set memory allocation and deallocation hooks, using _CrtSetAllocHook.

Puppy
  • 144,682
  • 38
  • 256
  • 465
  • @sharptooth: If you're trying to debug something, it's not unreasonable to have it in a debug build. – Puppy Apr 07 '11 at 08:29
  • Sure, just debug builds are relatively slow and this limits their use when some huge amount of data needs to be processed. – sharptooth Apr 07 '11 at 08:33
  • @sharptooth +1 indeed but it would be nice to have something that works for release builds too. Debug is just too slow (yes I know turning on optimizations would help some). – paperjam Apr 07 '11 at 08:34
  • 1
    @paperjam: Well, this is the only mechanism present in VC++ runtime for this purpose. You could try to enable optimizations and still link against the debug CRT. – sharptooth Apr 07 '11 at 08:50
1

You can hook the HeapAlloc function, which malloc calls internally, by using the Detours library.

kbjorklu
  • 1,338
  • 8
  • 10
1

http://msdn.microsoft.com/en-us/library/aa366778%28v=vs.85%29.aspx

If you clear the IMAGE_FILE_LARGE_ADDRESS_AWARE flag in VS's linker options, the program's heap will be limited to 2GB in size, and should crash if attempts are made to acquire memory that would put it over that limit.

  • Nice, but I'm guessing this will only work for 32-bit builds. – paperjam Apr 07 '11 at 12:38
  • So long as the flag is explicitly cleared, the 2GB limit will exist when compiling for 64 bit as well, because the flag is set by default for x64 targets, and cleared for x86 targets. – Riley Barnett Apr 07 '11 at 12:49