By default, access to each heap created is serialized, which prevents
multiple threads in the same process from simultaneously accessing the heap. There is a
small performance cost to serialization, but mutual exclusion must be used whenever two
threads heap usage might collide with a strong possibility of causing corruption of the
heap.
Setting the HEAP_NO_SERIALIZE flag when the heap is created, or when a particular heap
function is used, eliminates this default mutual exclusion on the heap. This flag can be
safely set if only one thread accesses the heap or if the process uses another form of
mutual exclusion, e.g. a mutex object, to keep multiple threads from accessing the heap at
the same time. Specifying the HEAP_NO_SERIALIZE flag improves overall heap performance
slightly and means the heap needs less memory overhead to maintain itself.
Interestingly enough, access to the default heap is serialized so there is no need to
worry about multiple threads in a process corrupting the default heap.
Specifying the HEAP_GENERATE_EXCEPTIONS flag when the heap is created or when memory is
allocated or reallocated from a heap, specifies that the heap manager will raise an
exception to indicate a heap allocation function failure, rather than returning NIJLL.
This flag is a useful feature if you have exception handling built into your application.
Exception handling can be an effective way of triggering special events, such as low
memory situations, in your application. Exception values on such exceptions are
STATUS_NO_MEMORY if the allocation failed for lack of memory or
STATUS_ACCESS_VIOLATION if the allocation failed because of heap corruption or improper
function parameters.
Specifying the HEAP_ZERO_MEMORY flag when memory is allocated or reallocated from a
heap, specifies that the allocated memory will be initialized to zero values which is not
the default.
Memory allocated from a heap is not moveable, so allocating and freeing many small
different-size blocks may fragment the heap, over time. However, if a block is reallocated
and there is not enough room to reallocate the memory in place, the system will attempt to
move the memory block. This will happen by default, unless the HEAP_REALLOC_IN_PLACE_ONLY
flag is specified when heap memory is reallocated, in which case the function returns with
failure status rather than move the memory. Relocatable blocks will help prevent the heap
from becoming fragmented.