locked
Windows Heap vs. CRT Heap RRS feed

  • Question

  • Hi, I'm trying to put together some detailed memory usage analysis functions and am a bit confused on the heap(s) used by a simple unmanaged c++ program. 

    It appears that all memory I allocate with new/malloc goes to the CRT heap.  I can get information on this heap with functions like _CrtMemCheckpoint().

    It also appears that there are 4 Windows heaps that are returned from a call to GetProcessHeaps().  Are the Windows heaps built on top of the CRT heap, is it the other way around? or are the two completely seperate?

    Are the Windows heaps only used by calls to functions like HeapAlloc, LocalAlloc, GlobalAlloc, etc?  If I never explicitly call these functions will these 4 process heaps not grow beyond their current size?  Do calls to functions like CreateThread and CreateFile allocate memory on these process heaps?

    I'm trying to figure out my total memory usage and am fairly content by observing that all memory allocated with new/malloc can be observed with _CrtMemCheckpoint() but was wondering if my program could be using other memory that _CrtMemCheckpoint() might not observe.

    Thanks in advance for any help!

    -Pace
    Monday, July 7, 2008 10:46 PM

Answers

  • Are the Windows heaps built on top of the CRT heap, is it the other way around?

    It's the other way around. The CRT creates its own private heap.

    Here's a little gotcha: Each CRT does this. If you link against more than 1 CRT, you'll have multiple CRT heaps.

    Do calls to functions like CreateThread and CreateFile allocate memory on these process heaps?

    If you're referring to the actual kernel object that's created, then no, that gets allocated from kernel memory. (Paged pool, I think).

    I'm trying to figure out my total memory usage and am fairly content by observing that all memory allocated with new/malloc can be observed with _CrtMemCheckpoint() but was wondering if my program could be using other memory that _CrtMemCheckpoint() might not observe.

    Jump into a debugger like CDB or WinDBG, and run !heap, that'll tell you what heaps are in your process and allows you to look at each allocated block (plus a lot more, see the manual).

    You can also step through heap creation either on a per-module load basis, or by breaking on ntdll!RtlCreateHeap.

    For the former,

    1) sxe ld; * Will break on module loads
    2) .restart
    3) g, or !heap (to proceed with the next module or inspect the heaps respectively)

    And the latter:

    1) sxe ld
    2) .restart
    3) bp ntdll!RtlCreateHeap
    4) g


    Futher reading:

    http://msdn.microsoft.com/en-us/library/ms810466.aspx
    http://msdn.microsoft.com/en-us/library/ms810603.aspx
    • Edited by scorpion007 Tuesday, July 8, 2008 5:38 AM typo
    • Marked as answer by Pace1 Tuesday, July 8, 2008 2:08 PM
    Tuesday, July 8, 2008 5:32 AM

All replies

  • I've got part of an answer.  The first heap you get from GetProcessHeaps() is the default process heap, the one you get from GetProcessHeap().  GlobalAlloc, LocalAlloc and CoTaskMemAlloc() allocate from that heap.  The 4th one is the one created by the CRT startup code.  Any memory allocated by new or malloc() comes from that heap.  No idea what the 2nd and 3rd heaps are.   Note that the heap handle values correspond with their address in memory.
    Hans Passant.
    Tuesday, July 8, 2008 2:26 AM
  • Are the Windows heaps built on top of the CRT heap, is it the other way around?

    It's the other way around. The CRT creates its own private heap.

    Here's a little gotcha: Each CRT does this. If you link against more than 1 CRT, you'll have multiple CRT heaps.

    Do calls to functions like CreateThread and CreateFile allocate memory on these process heaps?

    If you're referring to the actual kernel object that's created, then no, that gets allocated from kernel memory. (Paged pool, I think).

    I'm trying to figure out my total memory usage and am fairly content by observing that all memory allocated with new/malloc can be observed with _CrtMemCheckpoint() but was wondering if my program could be using other memory that _CrtMemCheckpoint() might not observe.

    Jump into a debugger like CDB or WinDBG, and run !heap, that'll tell you what heaps are in your process and allows you to look at each allocated block (plus a lot more, see the manual).

    You can also step through heap creation either on a per-module load basis, or by breaking on ntdll!RtlCreateHeap.

    For the former,

    1) sxe ld; * Will break on module loads
    2) .restart
    3) g, or !heap (to proceed with the next module or inspect the heaps respectively)

    And the latter:

    1) sxe ld
    2) .restart
    3) bp ntdll!RtlCreateHeap
    4) g


    Futher reading:

    http://msdn.microsoft.com/en-us/library/ms810466.aspx
    http://msdn.microsoft.com/en-us/library/ms810603.aspx
    • Edited by scorpion007 Tuesday, July 8, 2008 5:38 AM typo
    • Marked as answer by Pace1 Tuesday, July 8, 2008 2:08 PM
    Tuesday, July 8, 2008 5:32 AM