Background
The operating system provides memory via VirtualAlloc() only. That works fine, but the granularity is not good: it can only provide 64kB at a time. That's why Microsoft has implemented different heap managers, e.g. the C++ heap manager or the .NET heap manager. Those get memory from the OS in 64kB blocks and provide it to a C++ or .NET program in smaller chunks.
!heap
and related commands only work for the C++ heap manager. To inspect the .NET heap, you need the sos extension for WinDbg.
Regarding your questions
As far as I can tell VirtualAlloc bypasses the gflags/!heap extensions?
The GFlags +ust
flag is specific to C++ heap allocations. The !heap
commands are also specific to the C++ heap manager, so yes, none of these will care about VirtualAlloc() calls.
However, I would not say, VirtualAlloc() "bypasses" them, which would be a statement that it goes through the C++ heap manager. It's rather the opposite: it's on a lower level than the heap manager operates.
a) !heap walks the list of allocated memory in each heap - but not the allocated memory that came from VirtualAlloc
Yes, for the same reason.
b) when you allocate a huge chunk of memory via new/malloc that goes to LocalAlloc() and then to VirtualAlloc() where it bypasses the call stack logging
Basically yes. There is a point where it's no longer worth to split the memory into smaller regions. Obviously allocating 64kB for a 2 byte variable is too much waste.
Microsoft drew the line at ~ 512 kB as documented in HeapAlloc (look for the term 0x7FFF8). So when you allocate more than 512 kB, it will not use the heap manager any more but the raw memory block of VirtualAlloc(). In the worst case, there's an overhead of 12% (64kB waste when you allocate 512kB + 1 Byte).
Don't worry
There are other tools to recognize larger memory leaks that arise from VirtualAlloc(). The WinDbg command !address
is helpful and Rohitab API monitor can help. As suggested by others, you can also try LeakDiag or commercial memory leak analyzers.