Memory Management

Every Windows NT process automatically has one heap called the default heap and may optionally nave as many other dynamic heaps as they wish, by creating and destroying them on the fly. There is no difference between them. The Win32 global and local heap memory management functions, like GlobalAlloc() and LocalAlloc(), use the default process heap. The C run-time library memory management functions, like malloc() , may use the default heap, depending on the implementation. The GetProcessHeap() function returns a handle to the default heap for a process. This handle can be used in all calls which take a heap handle except HeapDestroy() . Functions such as GlobalAlloc() or malloc() simply call Get ProcessHeap() to retrieve a handle to the default heap, and then manage memory accordingly.

Both default and dynamic heaps have a specific amount of reserved and committed memory regions associated with them initially, but they behave differently with respect to these limits. The default heap’s initial reserved and committed memory region sizes are designated when the application is linked. Visual C++ supports the -HEAPSIZE [reserve] [,commit] switch to affect the heap or you can link your application with a module definition file and include a HEAPSIZE [reserve] [commit] statement in it. By default, commit (4k) is less than reserve (1Mb).

Each application carries this information within its executable image information. You can view this information by dumping header information for the executable image by typing

dumpbin -headers <exename>

Since the minimum range of address space that can be reserved is 16 pages (64K), the loader will reserve at least 16 pages for the application heap at load time, no matter what the executable image says.

Generally with any heap, and also with the process stack, when commit is less than reserve, memory demands are reduced but execution time is marginally slower. This is because the system sets up guard pages around the heap and stack and could have to process guard page faults. When the heap or stack grows big enough, the guard pages are accessed outside the committed area causing a guard page fault, which tells the system to map in another page. The application continues to run as if you had originally had the new page committed. If the committed memory is equal to the reserve, no guard pages are created and the program faults if it goes outside the committed memory area.

In some cases the default heap needs to allocate more memory than is available in its current reserved address space. In these cases the default heap may respond differently to a dynamic heap. Instead of failing an allocation request, the default heap manager reserves an additional 1 Mb address range elsewhere in the process and commits as much memory as it needs from this reserved address range to satisfy the allocation request. The default heap manager is then responsible for managing this new memory region, transparently to the application, as well as the original heap space. If necessary, it will repeat this as necessary until the process runs out of physical memory and/or logical address space.

That is why managing the initial heap parameters is important. The time taken to locate and reserve a new range of addresses in a process can be saved by reserving a large enough address range initially. Each application has 2 GB of virtual address space and requires relatively little physical memory to support it.

previous page next page