4. AMC (Automatic Mostly-Copying)

AMC is a general-purpose automatically managed pool class. This is the most mature pool class in the MPS, intended for the majority of objects in the client program. Use this pool class unless you need a particular feature that it doesn’t provide.

“Mostly Copying” means that it uses copying garbage collection except for blocks that are pinned by ambiguous references.

It uses generational garbage collection. That is, it exploits assumptions about object lifetimes and inter-connection variously referred to as “the generational hypothesis”. In particular, the following tendencies will be efficiently exploited by an AMC pool:

  • most objects die young;

  • objects that don’t die young will live a long time.

4.1. AMC properties

4.2. AMC interface

#include "mpscamc.h"
mps_pool_class_t mps_class_amc(void)

Return the pool class for an AMC (Automatic Mostly-Copying) pool.

When creating an AMC pool, mps_pool_create_k() requires one keyword argument:

It accepts three optional keyword arguments:

  • MPS_KEY_CHAIN (type mps_chain_t) specifies the generation chain for the pool. If not specified, the pool will use the arena’s default chain.

  • MPS_KEY_INTERIOR (type mps_bool_t, default TRUE) specifies whether ambiguous interior pointers to blocks in the pool keep objects alive. If this is FALSE, then only client pointers keep objects alive.

  • MPS_KEY_EXTEND_BY (type size_t, default 4096) is the minimum size of the memory segments that the pool requests from the arena. Larger segments reduce the per-segment overhead, but increase fragmentation and retention.

For example:

MPS_ARGS_BEGIN(args) {
    MPS_ARGS_ADD(args, MPS_KEY_FORMAT, fmt);
    res = mps_pool_create_k(&pool, arena, mps_class_amc(), args);
} MPS_ARGS_END(args);

When creating an allocation point on an AMC pool, mps_ap_create_k() accepts one optional keyword argument:

  • MPS_KEY_AP_HASH_ARRAYS (type mps_bool_t, defaulting to false) specifies (if true) that blocks allocated from the allocation point do not contribute to the new size of the nursery space for the purposes of deciding whether to start a collection of that generation. See Hash arrays.

4.3. Hash arrays

The location dependency feature of the MPS allows the client program to implement address-based hash tables in pools like AMC that use a moving memory manager, re-hashing the tables when the addresses they contain might have moved.

However, when a frequently-used hash table grows large enough, the following sequence of events may take place:

  1. The hash table discovers that its location dependency is stale.

  2. A new array is allocated to contain the re-hashed keys.

  3. The new array is large enough to push the new size of the nursery space (that is, the amount of newly allocated memory since the last collection in the first generation in the generation chain for the pool containing the array) close to its capacity.

  4. A small amount of additional allocation causes the new size of the nursery generation to exceed its capacity, which causes the MPS to start a new collection of that generation. This in turn causes the hash table to become stale again.

When the hash table reaches this critical size, the client program may find that a large fraction of its time is being spent re-hashing the table.

In order to avoid this happening, the MPS provides a mechanism for specifying that the newly allocated array does not contribute to the new size of the nursery space: this cuts off the vicious cycle at step 3.

To enable this mechanism, use the optional MPS_KEY_AP_HASH_ARRAYS keyword argument when creating an allocation point with mps_ap_create_k(). This interface is documented in the AMC Interface section of the AMC (Automatic Mostly-Copying) documentation above.

See Scheduling of collections for an explanation of the new size of a generation, and how the MPS uses this to determine when to start a collection of that generation.