The Small-Block Heap, the C++ new and delete Operators, and _heapmin

You can use the Windows HeapAlloc function in your programs, but you're more likely to use the malloc and free functions supplied by the CRT. If you write C++ code, you won't call these functions directly; instead, you'll use the new and delete operators, which map directly to malloc and free. If you use new to allocate a block larger than a certain threshold (480 bytes is the default), the CRT passes the call straight through to HeapAlloc to allocate memory from a Windows heap created for the CRT. For blocks smaller than the threshold, the CRT manages a small-block heap, calling VirtualAlloc and VirtualFree as necessary. Here is the algorithm:

  1. Memory is reserved in 4-MB regions.

  2. Memory is committed in 64-KB blocks (16 pages).

  3. Memory is decommitted 64 KB at a time. As 128 KB becomes free, the last 64 KB is decommitted.

  4. A 4-MB region is released when every page in that region has been decommitted.

As you can see, this small-block heap takes care of its own cleanup. The CRT's Windows heap doesn't automatically decommit and unreserve pages, however. To clean up the larger blocks, you must call the CRT _heapmin function, which calls the windows HeapCompact function. (Unfortunately, the Windows 95 version of HeapCompact doesn't do anything—all the more reason to use Windows NT.) Once pages are decommitted, other programs can reuse the corresponding swap file space.

In previous versions of the CRT, the free list pointers were stored inside the heap pages. This strategy required the malloc function to "touch" (read from the swap file) many pages to find free space, and this degraded performance. The current system, which stores the free list in a separate area of memory, is faster and minimizes the need for third-party heap management software.

If you want to change or access the block size threshold, use the CRT functions _set_sbh_threshold and _get_sbh_threshold.

A special debug version of malloc, _malloc_dbg, adds debugging information inside allocated memory blocks. The new operator calls _malloc_dbg when you build an MFC project with _DEBUG defined. Your program can then detect memory blocks that you forgot to free or that you inadvertently overwrote.