<aside> 🌐 https://ghostscript.com/r/Ghostscript-Memory-Management-Overview

</aside>

Ghostscript/GhostPDL memory management is based around what we term “allocators”. Those are built around the gs_memory_t object.

Heap Allocator

Starting at the “lowest” level, we have the “heap allocator” (base/gsmalloc.c). The heap allocator is slightly special in that there should only be one instance

Multiple Allocator Instances

As is possibly implied by the description, the chunk allocator can have several instances in existence at a given time.

Although not restricted to the garbage collector, struct descriptors can also, optionally include a “finalize” method, which the memory manager will call when instances of that

An important point to note about the garbage collector: an clump allocator with the garbager attached can effectly request that the garbage collector be run. But it is up to the Postscript interpreter to actually initiate garbage collection.

Reference Counting

Ghostscript also makes of reference counting. Reference counted objects have a ‘substructure’ (named ‘rc’) embedded in them containing the reference count itself, plus the memory allocator used in the creation of the object.

It is extremely important to realise that any allocator can be used to create a reference counted object: non-garbage collected, garbage collected, stable or non-stable.

All but the first of those is, frankly, counter-intuitive, since neither the garbage collector, nor the Postscript save/restore mechanism take any account of the reference count of an object. Thus, if the object was created in Postscript memory, it can be freed by a restore even if the reference count is greater than 0. Also, if it was allocated in garbage collected memory, and reaches a point where no other objects in garbage collected memory reference it, the object can be freed by the garbage collector even if the reference count is greater than 0.

It is best practice to avoid adding new reference counted objects allocated in anything other than a non-garbage collected allocated, if possible.

Identifying Which Allocator Was Used To Create An Object

Conventionally, non-trivial, long lived objects/structures in Ghostscript contain a pointer to the allocator use to allocate them. This will be a gs_memory_t pointer called either ‘memory’ or ‘mem’ - in the case of reference counted objects, in the ‘rc’ substructure, and called ‘memory’. The gs_memory_t structure contains several pointers: