Zone memory

The Zone memory system is an internal memory allocator used by Doom for memory management. Due to technology at the time of Doom's release, memory allocation was considered an expensive operation. Presumably due to the inadequacies of memory management functions available in DOS at the time of Doom's development, Doom includes its own memory allocator.

In a normal C program, memory is allocated and deallocated using the C functions  and. The zone memory code contains its own implementations of these,  and.

Rather than calling low-level memory management routines such as, zone heaps allocate a single, large, continuous block of RAM using the normal system malloc at the beginning of execution and then divide this large block into smaller ones, keeping all the blocks linked together in a list. When two or more free blocks touch each other, the blocks are merged together to keep the list length short. This helps keep search times for a free block of memory shorter and prevents unnecessary external fragmentation (if blocks are too small, no future allocation may be able to fit into them).

Domain-specific allocation lifetimes
The  function differs from the C   function in that it includes support for "tags." Each piece of memory has a particular tag which indicates its purpose and determines its allocation lifetime. Memory blocks are treated differently according to their tags.

The simplest tag is the PU_STATIC tag which specifies a piece of memory which must be explicitly deallocated with the  function. From a programmer's point of view, using the functions in this way is identical to using C's memory functions.

More interesting is the PU_CACHE tag. Memory allocated with this tag may be automatically freed back to the system if it runs out of memory. In this way, caching of WAD file data is possible. It is common, for example, to load data from a WAD resource with the PU_STATIC tag, and when operations on that data have completed, change the tag of the area of memory (using the  function) to PU_CACHE. If the system is low on memory, the data may be freed, but otherwise it will be kept in memory for future use. The WAD loading code interacts with the zone memory system to provide this capability, and it was mostly important in Doom as a means to reduce disk reading time.

The other interesting tag is the PU_LEVEL tag. All memory related to the current game level is allocated with the PU_LEVEL tag. When the level exits, the zone memory is searched and all pieces of memory allocated with this tag are freed. This relieves the burden of having to individually free each piece of memory related to the level. It is possible this is inspired by the garbage collector provided by Objective C (Doom was developed on NeXT machines which used Objective C, and the original Doom editor was written in it).

Advanced diagnostics
The zone memory system also augmented Doom by providing advanced debugging and diagnostics features that are not available through the standard library memory routines. Amongst these are some of the following:


 * Sentinel words to guard against buffer overflows. These are the source of the dreaded "Freed a pointer without ZONEID" messages caused by poorly made maps. All memory blocks have the ZONEID ( in the original source) written into their header, and if it is wrong during any memory operation, the game engine knows that its heap has been corrupted.


 * Complete heap verification. The engine can stop to trace its way across the entire heap and verify that everything is correctly arranged. This is done after extensive operations such as loading save games.


 * Ability to dump the heap to a text file to look for errors or for ways to improve memory allocation.

Anecdotes
The file  in the Doom source code contains an anecdote that John Carmack considered the zone memory system in Doom "the only stuff that might have been useful for Quake".

The zone allocator was vastly improved in the Boom source port. Lee Killough remarked in the  file that while it was neat, it was only neat enough to be rewritten.