Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any useful suggestions to figure out where memory is being free'd in a Win32 process?

An application I am working with is exhibiting the following behaviour:

  1. During a particular high-memory operation, the memory usage of the process under Task Manager (Mem Usage stat) reaches a peak of approximately 2.5GB (Note: A registry key has been set to allow this, as usually there is a maximum of 2GB for a process under 32-bit Windows)

  2. After the operation is complete, the process size slowly starts decreasing at a rate of 1MB per second.

I am trying to figure out the easiest way to quickly determine who is freeing this memory, and where it is being free'd.

I am having trouble attaching a memory profiler to my code, and I don't particularly want to override the new/delete operators to track the allocations/deallocations (IOW, I want to do this without re-compiling my code).

Can anyone offer any useful suggestions of how I could do this via the Visual Studio debugger?


Update

I should also mention that it's a multi-threaded application, so pausing the application and analysing the call stack through the debugger is not the most desirable option. I considered freezing different threads one at a time to see if the memory stops reducing, but I'm fairly certain this will cause the application to crash.

like image 213
LeopardSkinPillBoxHat Avatar asked Nov 05 '22 16:11

LeopardSkinPillBoxHat


1 Answers

Ahh! You're looking at the wrong counter!

Mem Usage doesn't tell you that memory is being freed. Only that the working set is being purged! This could mean some other application needs memory, or the VMM decided to mark some of your process's pages as Stand By for some other process to quickly use. It does not mean that VirtualFree, HeapFree or any other free function is being called.

Look at the commit size (VM Size, Private Bytes, etc).

But if you still want to know when memory is being decommitted or freed or what-have-you, then break on some free calls. E.g. (for Visual C++)

{,,kernel32.dll}HeapFree

or

{,,msvcr80.dll}free

etc.

Or just a regular function breakpoint on the above. Just make sure it resolves the address.

cdb/WinDbg let you do it via

bp kernel32!HeapFree
bp msvcrt!free

etc.

Names may vary depending on which CRT version you use and how you link against it (via /MT or /MD and its variants)

like image 96
Alex Budovski Avatar answered Nov 11 '22 12:11

Alex Budovski