.. Sources:
`<https://info.ravenbrook.com/project/mps/master/manual/wiki/pool_classes.html>`_
`<https://info.ravenbrook.com/project/mps/master/design/poolamc/>`_
.. index::
single: AMC pool class
single: pool class; AMC
.. _pool-amc:
AMC (Automatic Mostly-Copying)
==============================
**AMC** is a general-purpose :term:`automatically managed <automatic
memory management>` :term:`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 :term:`copying garbage collection`
except for blocks that are :term:`pinned <pinning>` by
:term:`ambiguous references`.
It uses :term:`generational garbage collection`. That is, it exploits
assumptions about object lifetimes and inter-connection variously
referred to as "the :term:`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.
.. index::
single: AMC pool class; properties
AMC properties
--------------
* Does not support allocation via :c:func:`mps_alloc` or deallocation
via :c:func:`mps_free`.
* Supports allocation via :term:`allocation points`. If an allocation
point is created in an AMC pool, the call to
:c:func:`mps_ap_create_k` takes no keyword arguments.
* Supports :term:`allocation frames` but does not use them to improve
the efficiency of stack-like allocation.
* Does not support :term:`segregated allocation caches`.
* Garbage collections are scheduled automatically. See
:ref:`topic-collection-schedule`.
* Uses :term:`generational garbage collection`: blocks are promoted
from generation to generation in the pool's chain.
* Blocks may contain :term:`exact references` to blocks in the same or
other pools (but may not contain :term:`ambiguous references` or
:term:`weak references (1)`, and may not use :term:`remote
references`).
* Allocations may be variable in size.
* The :term:`alignment` of blocks is configurable.
* Blocks do not have :term:`dependent objects`.
* Blocks that are not :term:`reachable` from a :term:`root` are
automatically :term:`reclaimed`.
* Blocks are :term:`scanned <scan>`.
* Blocks may be referenced by :term:`interior pointers` (unless
:c:macro:`MPS_KEY_INTERIOR` is set to ``FALSE``, in which case only
:term:`base pointers`, or :term:`client pointers` if the blocks
have :term:`in-band headers`, are supported).
* Blocks may be protected by :term:`barriers (1)`.
* Blocks may :term:`move <moving garbage collector>`.
* Blocks may be registered for :term:`finalization`.
* Blocks must belong to an :term:`object format` which provides
:term:`scan <scan method>`, :term:`skip <skip method>`,
:term:`forward <forward method>`, :term:`is-forwarded <is-forwarded
method>`, and :term:`padding <padding method>` methods.
* Blocks may have :term:`in-band headers`.
.. index::
single: AMC pool class; interface
AMC interface
-------------
::
#include "mpscamc.h"
.. c:function:: mps_pool_class_t mps_class_amc(void)
Return the :term:`pool class` for an AMC (Automatic
Mostly-Copying) :term:`pool`.
When creating an AMC pool, :c:func:`mps_pool_create_k` requires
one :term:`keyword argument`:
* :c:macro:`MPS_KEY_FORMAT` (type :c:type:`mps_fmt_t`) specifies
the :term:`object format` for the objects allocated in the pool.
The format must provide a :term:`scan method`, a :term:`skip
method`, a :term:`forward method`, an :term:`is-forwarded
method` and a :term:`padding method`.
It accepts three optional keyword arguments:
* :c:macro:`MPS_KEY_CHAIN` (type :c:type:`mps_chain_t`) specifies
the :term:`generation chain` for the pool. If not specified, the
pool will use the arena's default chain.
* :c:macro:`MPS_KEY_INTERIOR` (type :c:type:`mps_bool_t`, default
``TRUE``) specifies whether :term:`ambiguous <ambiguous
reference>` :term:`interior pointers` to blocks in the pool keep
objects alive. If this is ``FALSE``, then only :term:`client
pointers` keep objects alive.
* :c:macro:`MPS_KEY_EXTEND_BY` (type :c:type:`size_t`,
default 4096) is the minimum :term:`size` of the memory segments
that the pool requests from the :term:`arena`. Larger segments
reduce the per-segment overhead, but increase
:term:`fragmentation` and :term:`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);