All Manuals > LispWorks® User Guide and Reference Manual > 11 Memory Management

11.4 Memory Management in 64-bit LispWorks

This section describes the garbage collector (GC) in 64-bit LispWorks.

11.4.1 General organization of memory

The memory in 64-bit LispWorks is arranged in segments, which belong to generations. Unlike 32-bit LispWorks, segments are sparsely allocated in memory, that is they are not contiguous.

Each segment has an allocation type, which defines the type of objects that the segment contains. The system creates and destroys segments as needed. A generation may or may not contain a segment for a specific allocation type, and a generation may contain more than one segment for any particular allocation type. Segments may change in size.

You can see the allocation for each allocation type in the output of:


Additionally you can see the segments of each generation in the output of:

(room t)

After the total allocation in each generation, this prints the allocation type for each segment followed by the hexadecimal address range for allocating objects.

You can also use:

(room :full)

which does not produce segments information, but prints allocated amounts by allocation types.

11.4.2 Segments and Allocation Types

Some GC interface functions take an allocation type as an argument, which is one of the keywords below. There are two categories of allocation type.

The main allocation types, which can be used as the what argument to the function apply-with-allocation-in-gen-num, are:

The segment contains only conses.
The segment contains only symbols (and does not include symbol names or any of the other properties of symbols).
The segment contains only function objects.

The segment contains only objects that do not contain pointers (strings, specialized numeric arrays, double-floats).

The segment contain other objects, that is any object that contain pointers, and is not a symbol, cons or a function.

The derived allocation types are:

The segment contains a mixture of :other, :function and :symbol, but not :cons or :non-pointer.

The segment contains cons objects that are static.


The segment contains objects that do not contain pointers and are static (currently stacks are also allocated in these segments).

The segment contains a mixture like :mixed, but static.
The segment contains weak objects (arrays, and internals of weak hash tables).
The segment contains a single very large simple vector. The vector is static.

The segment contains a single very large non-pointer object (a string or a specialized numeric array). The vector is static.

Segments of allocation type :other-big or :non-pointer-big can be as large as required to hold their object.

For all other allocation types, the size of each single segment is restricted. The implementation limit is currently 256 MB, and you can specify a smaller limit using set-maximum-segment-size.

11.4.3 Garbage Collection Operations

In 64-bit LispWorks there are two methods of garbage collection: copy (the default for all non-static objects) and mark and sweep (also referred to simply as mark) for static objects and under user control.

The two methods can be mixed within the same garbage collection operation and generation, but a segment is collected using only one of mark or copy in a given operation.

When a segment is collected using the copying method, the objects within it can either be copied to another segment in the same generation or can be copied to a segment in a higher generation. The latter case is called promotion. The automatic garbage collection copies with promotion until the objects reach the blocking generation, which is collected in a specific way as described in 11.4.4 Generation Management.

11.4.4 Generation Management

In general, higher generations contain objects that live longer and are therefore much less likely to die. Each garbage collection only collects the generations up to some number, and never reclaims the objects in higher generations.

Objects move between generations by being promoted. For most allocation types, this means that the GC copies the objects from a segment in one generation to a segment in a higher generation. For allocation types :other-big and :non-pointer-big, the objects are not actually copied when they are promoted; but instead the whole segment is re-attached to the higher generation. The automatic garbage collection promotes objects until they reach the blocking generation.

In the default configuration, there are 8 generations, numbered from 0 to 7. Generation 7 is used to keep objects that survived saving the image. Generations 4, 5 and 6 are not used. Generation 3 is the blocking generation, where long-lived objects accumulate. Generations 0,1, and 2 are ephemeral, and objects that survive a garbage collection in each of these generations are promoted to the next generation.

11.4.5 Tuning the garbage collector

The GC settings are tuned for typical cases, so in general you do not need to change them. If you are considering tuning the GC, contact Lisp Support.

The main tools for seeing how the GC behaves are the macro extended-time and periodical calls to room.

In the output of (room) (or the more verbose (room t)), the allocation in each generation is presented according to the allocation type, which may be useful to decide on possible tuning.

(extended-time forms) outputs the time spent in garbage collection, whether automatic or called explicitly. The time is shown according to the maximum generation number that was collected and to whether it was a standard garbage collection (automatic and calls to gc-generation) or a marking garbage collection (calls to marking-gc).

In addition to room and extended-time, there are also the functions count-gen-num-allocation, gen-num-segments-fragmentation-state, and set-automatic-gc-callback. These function can be used to collect information about automatic garbage collection operations.

The profiler can also help determine whether the settings can be improved for your application. See 12 The Profiler for details of that. Interface for tuning the GC

The main interfaces are those which control the blocking generation.

For generations lower than the blocking generation, objects that survive are promoted, and the system does not automatically promote objects to higher generations. Thus if the application generates long-lived objects, they will accumulate in the blocking generation.

The behavior when the blocking generation grows is controlled by set-blocking-gen-num and set-gen-num-gc-threshold. It may also be useful to set the maximum segment size with set-maximum-segment-size.

Explicit garbage collection can be done by calling gc-generation and marking-gc. Since repeated use of marking-gc will cause a lot of fragmentation, the arguments what-to-copy and max-size-to-copy can be used to specify that part of the data should be collected by copying.

gc-generation can also be used to promote objects to a higher generation than the blocking generation.

It is normally less important to tune the ephemeral segments, that is the segments below the blocking generation. Functions that may be useful include set-default-segment-size, set-spare-keeping-policy and set-delay-promotion.

LispWorks® User Guide and Reference Manual - 01 Dec 2021 19:30:20