The Memory Pool System
The Memory Pool System
Flexibility The MPS must fit into a number of different products 4. IMPLEMENTATION
and meet differing requirements in diverse environments. It The MPS is about 62 Kloc of extremely portable ISO standard C
must do this with as little modification as possible, so that [1]. Except for a few well-defined interface modules, it is freestand-
it can be deployed at low cost. Flexibility gives the MPS ing (doesn’t depend on external libraries1 ). We have been known
broad application, and reduces the need to maintain special to port to a new operating system in less than an hour.
versions of the MPS for different clients. Code re-use also The code is written to strict standards. It is heavily asserted, with
leads to robustness through use testing. checks on important and subtle invariants. Every data structure
has a run-time type signature, and associated consistency check-
Reliability Memory management defects are very costly. In de- ing routines which are called frequently when the MPS is compiled
velopment they are difficult to find and fix, and once de- in “cool” mode2 . Much of the code has been put through formal
ployed they are virtually impossible to reproduce. The MPS code inspection (at 10 lines/minute or less) by between four and
may be shipped to third and fourth parties, further increasing six experienced memory management developers [15]. It was de-
the cost of a defect. Reliability is therefore very important to veloped by a team working at approximately Capability Maturity
the viability of the MPS. Model level 3 [CMMI1.02]. As a result, it is extremely robust, and
has a very low defect rate.
Efficiency Efficiency will always be required by clients; after all, The MPS is designed to work efficiently with threads, but is
memory management is about the efficient utilization of re- not currently multi-threaded. Fast allocation is achieved by a non-
sources to meet requirements. However, the tradeoffs be- locking in-line allocation mechanism (see section 5.2).
tween those requirements will differ from application to ap-
plication, hence the need for adaptability and flexibility. A
generally efficient system will make it easier to meet these 5. KEY FEATURES AND ATTRIBUTES
requirements.
5.1 Flexible combination of memory manage-
3. ARCHITECTURE ment techniques
The MPS consists of three main parts: The most important feature of the MPS is the ability to com-
bine memory management policies efficiently. In particular, mul-
1. the Memory Pool Manager (MPM) tiple instances of differing garbage collection techniques can be
combined. In the Harlequin Dylan system, for example, a mostly-
2. the pool classes, and copying main pool is combined with a mark-sweep pool for han-
dling weak key hash-tables, a manually-managed pool containing
3. the arena classes. guardians implementing user-level weakness and finalization, and a
mark-sweep pool for leaf objects. The same codebase is used with
See Figure 1. a very different configuration of pools in the Harlequin R RIP3 .
Each pool class may be instantiated zero or more times, creating An overview of the abstractions that allow flexible combination
a pool. A pool contains memory allocated for the client program. can be found in section 6.
The memory is managed according to the memory management
policy implemented by its pool class. For example, a pool class Ironically, a lot of clever design went into the interfaces (MPM
may implement a type of garbage collection, or manage a partic- and the plinth) to make robust and efficient binary interfaces for a
ular kind of object efficiently. Each pool can be instantiated with closed-source
MPS library.
different parameters, creating variations on the policy. The MPS can be compiled with various flags to give different va-
The arena classes implement large-scale memory layout. Pools rieties. The “cool” varieties are intended for debugging and testing.
The “hot” varieties are for delivery. Some level of internal consis-
allocate tracts of memory from the arena in which they manage tency checking is present in all varieties.
client data. Some arena classes use virtual memory techniques to The details of the Harlequin R RIP configuration and the the RIP-
give control over the addresses of objects, in order to make mapping specific pool class implementations are confidential, and not avail-
from objects to other information very efficient (critically, whether able under an open source licence.
Client Memory Pool
Inter- Pool manage Pools
Program Manager (MPM)
face Classes
contained by
Plinths faults
Memory /
Operating System manage Address
Space
which have a reference to any node in , that is, nothing black : , the equivalence-class relation induced by : and @ is called the
can refer to anything white. summary of each equivalence class of : . Roughly speaking, it
An initial partition is one with no black nodes: . All summarizes the set of zones to which that class refers. This is a
initial partitions are trivially reference partitions. BIBOP-like technique adapted from the Symbolics Lisp Machine’s
A final partition is one with no grey nodes: . hardware assisted garbage collection [18].
For a predicate , we say some reference partition The Tracer groups objects into segments, and maintains a con-
is a reference partition with respect to if and only if everything servative approximation of the summary of each segment. By do-
with is in , that is, . ing this, it is maintaining a reference partition with respect to each
If we can determine a final reference partition such that the client zone. Segments which don’t have a zone in their summary are
process roots are contained in then is unreachable by the “black” for that zone, segments which do are “grey” if they aren’t in
mutator, cannot affect future computation, and can be reclaimed. the zone, and “white” if they are. The Tracer uses this information
Tracing is a way of finding final reference partitions by refine- to refine traces during phase 1 of collection; see section 6.7.
ment. We start out by defining an initial reference partition with
respect to a “condemned” property, such as being a member of a 6.3 Segments
generation. We then move reachable objects from to , preserv- The Tracer doesn’t deal with individual client program objects.
All details of object allocation and format is delegated to the pool. 6.4 Reference Ranks for Ambiguity, Exact-
The Tracer deals with areas of memory defined by pool classes ness, Weakness, and Finalization
called segments. The segment descriptor contains these fields im- The rank of a reference controls the order in which references
portant to tracing: are traced while refining the reference partition. All references of
white The set of traces for which the segment is white. A superset lower numbered rank are scanned before any references of higher
of the union of the trace whiteness of all the objects in the rank. The current MPS implementation supports four ranks:
segment. More precisely, if a trace is not in the set, then the
segment doesn’t contain white objects for that trace. 1. ambiguous An ambiguous reference is a machine word which
may or may not be a reference. It must be treated as a refer-
grey The set of traces for which the segment is grey. (See “white” ence by the MPS in that it preserves its referent if it’s reach-
above.) able from the client process roots, but can’t be updated in
case it isn’t a reference, and so its referent can’t be moved.
summary A summary (see section 6.2) of all the references in the
Ambiguous references are used to implement conservative
segment.
garbage collection [7].
ranks A superset of the ranks of all the references in the segment
(see section 6.4). 2. exact An exact reference is definitely a reference to an object
if it points into a pool. Depending on the pool, the referent
In addition, the Tracer maintains a set of traces for which the may be moved, and the reference may be updated.
mutator is grey (and assumes it’s black for all other traces), and
a summary for the mutator. The mutator is a graph node which 3. final A final reference is just like an exact reference, except
consists of the processor registers, and any references in memory that a message (sometimes called a “near death notice”) is
that can’t be protected against transfers to and from the registers. sent to the client process if the MPS finds no ambiguous or
This is not usually the same as the root set. exact references to the referent. This mechanism is used to
Memory barriers4 are used to preserve the reference partitions implement finalization [17, 14].
represented by the traces in the face of mutation by the client pro-
4. weak A weak reference is just like an exact reference, except
cess. These invariants are maintained by the MPS at all times:
that it doesn’t preserve its referent even if it is reachable from
the client process roots. So, if no reachable ambiguous, ex-
Any segment whose grey trace set is not a subset of the mu-
tator’s grey trace set is protected from reads by the mutator. act, or final references are found, the weak reference is sim-
This prevents the mutator from reading a reference to a white ply nulled out. This mechanism is used to implement weak-
object when the mutator is black. If the mutator reads the ness.
segment, the MPS catches the memory exception and scans
the segment to turn it black for all traces in the difference be- Note that the pool which owns the reference may implement ad-
tween the sets. (An theoretical alternative would be to “un- ditional semantics. For example, when a weak reference is nulled
flip”, making the mutator grey for the union of the sets, but out, the AWL pool nulls out an associated strong reference in order
this would seriously set back the progress of a trace.) to support weak key hash tables.
Ranks are by no means a perfect abstraction. Parts of the Tracer
Any segment whose grey trace set is not a superset of the have to know quite a bit about the special semantics of ambiguous
mutator’s grey trace set is protected from writes by the mu- references. The Tracer doesn’t take any special action for final and
tator. This prevents the mutator from writing a reference to a weak references other than to scan them in the right order. It’s the
white object into a black object. If the mutator writes to the pools that implement the final and weak semantics. For example,
segment, the MPS catches the memory exception and makes the MRG pool class is one which implements the sending of near
the segment grey for the union of the sets. (An alternative death notices to the client process.
would be to “flip”, making the mutator black for the differ- The current implementation of the Tracer does not support seg-
ence between the sets, but this would generally be premature, ments with more than one rank, but is designed to be extended to
pushing the colletion’s progress along too fast.) do so.
Any segment which has a summary which is not a superset of The current MPS ordering puts weak after final, and is equivalent
the mutator’s summary is protected from writes by the muta- to Java’s “phantom references”. It would be easy to extend the
tor5 . If the mutator writes to the segment, the MPS catches MPS with additional ranks, such as a weak-before-final (like Java’s
the memory exception and unions the summary with the mu- “weak references”).
tator’s summary, removing the protection. Abstractly, this is
the same invariant as for the grey trace set (see above), be-
6.5 Scanning and Fixing
cause the summaries represent reference partitions with re- In order to allow pools to co-operate during a trace the MPS
spect to zones. The barrier prevents the mutator writing a needs a protocol for discovering references. This protocol is the
pointer to a white object (the zone) into a black object (which most time critical part of the MPS, as it may involve every object
doesn’t refer to the zone). that it is managing. The MPS protocol is both abstract and highly
A optimized.
The MPS uses memory protection (hardware memory barrier) for Each pool class may implement a scan and fix method. These
this, but could easily be adapted to a software barrier (if we have are used to implement a generic scan and generic fix method which
control over the compiler). The MPS abstraction of memory barri- dispatch to the pool’s method as necessary. The scan method maps
ers distinguishes between read and write barriers, even if the spe-
cific environment cannot. the generic fix method over the references in a segment. The fix
B
The current implementation of the MPS assumes that the muta- method preserves the referent of a reference (except when it is ap-
tor has a universal summary. In other words, it assumes that the plied to weak references), moving it out of the white set for one or
mutator could refer to any zone. This could be improved. more traces.
The most important optimization is part of the generic fix method large number of grey segments. This is how the MPS implements
which is inlined into the scan methods. The generic fix method first remembered sets.
looks up the reference in the interesting set (see section 6.7), which In a similar way, the MPS could also use the current status of
takes about three instructions. This eliminates almost all irrelevant other traces to refine the new trace. Imagine a large slow trace
references, such as references to generations which aren’t being which is performing a copying collection of three generations. A
collected, or references to objects not being managed by the MPS. fast small trace could condemn the old space of just one of the
A second level optimization in the generic fix method checks to generations. Any object which is black for the large trace is also
see if the reference is to a segment managed by the MPS, and then black for the small trace. Such refinement is not implemented in
whether the segment is white for any of the traces for which the the MPS at present.
reference is being fixed. This eliminates many more references. Note that these refinement steps could be applied at any time:
Only if a reference passes these tests is the pool’s fix method they are just refinements that preserve reference partitions. The
called. MPS currently only applies them during the condemn step.
A pool need not implement both scan and fix methods. A pool
which doesn’t contain references, but does contain garbage col- 6.7.2 Phase 2: Grey Mutator Tracing
lected objects, will have a “fix” method but no “scan” method. Note This phase most resembles a write-barrier non-moving garbage
that such objects are either black or white. A pool which contains collector [2]. Any segment “blacker” than the mutator is write pro-
references involved in tracing, but not garbage collected objects, tected (see section 6.3).
will have a “scan” method but no “fix” method. Such a pool would At this point the mutator is grey for the trace. Note that, at any
be a pool of roots, its objects either grey or black. A pool with stage, the mutator may be grey or black for different traces inde-
neither method is not involved in tracing, for example, a manually pendently. In addition, newly allocated objects are grey, because
managed pool storing strings. they are being initialized by the mutator.
An object can be moved provided that it is white for any trace for
6.6 Roots which the mutator is black, because the mutator can’t see references
Roots are objects declared to the MPS by the client process as to that object. [What about ambiguous references?]
being a priori alive. The purpose of tracing is to discover objects During phases 2 and 4 the Tracer makes progress by scanning
which aren’t referenced by transitive closure from the roots and segments which are grey for one or more traces (see section 6.5) in
recycle the memory they occupy. order to make them black. Thus we make progress towards a final
The MPS supports various kinds of roots. In particular, a thread reference partition (see section 6.1).
can be declared as a root, in which case its stack and registers are
scanned during a collection. 6.7.3 Phase 3: Flip
Roots have “grey” and “summary” fields just like segments, and Flipping for a set of traces means turning the mutator black for
may be protected from reads and writes by the mutator using the those traces. This may entail scanning the client process thread
same rules. However, roots are never white for any trace, since registers and any unprotectable data. The mutator can’t be running
their purpose is to be alive. while this is happening, so the MPS stops all mutator threads.
This is also the point at which the MPS sets the limit fields of
6.7 Five phase collection any formatted allocation points to zero, so that unscannable half-
The Tracer runs each trace through five phases designed to al- allocated objects are invalidated (see section 5.2).
low pools to co-operate in the same trace even though they may 6.7.4 Phase 4: Black Mutator Tracing
implement very different kinds of garbage collection.
This phase most resembles a read-barrier possibly-moving garbage
6.7.1 Phase 1: Condemn collector [6]. Any segment “greyer” than the mutator is read pro-
tected (see section 6.3).
The set of objects we want to try to recycle, the condemned set
At this point the mutator is black for the trace. In addition, newly
is identified, and a newly allocated trace is added to the white trace
allocated objects are black, and don’t need to be scanned.
set for the segments containing them.
At this stage, all segments containing any references (even the 6.7.5 Phase 5: Reclaim
white ones) are assumed to be grey for the trace, because we don’t
When the grey set for a trace is empty after flip then it represents
know whether they contain references to objects in the white set.
a final reference partition. The Tracer looks for segments which are
The roots are made grey for the trace, because they are a priori
white for the trace and calls the owning pool to reclaim the space
alive. The mutator is also assumed to be grey for the trace, because
occupied by remaining white objects within.
it has had access to all the grey data. Thus we start out with a valid
It’s up to the pool to decide whether to return the reclaimed space
initial reference partition (see section 6.1).
to its own free list, or to the arena.
We then use any existing reference partitions to reduce the num-
ber of grey segments for the trace as much as possible, using this
rule: Let be the set of reference partitions whose white sets are 7. FUTURE DIRECTIONS
supersets of the new white set. Any node which is in the union of The Memory Management Group at Harlequin was whittled away
the black sets of cannot refer to any member of the new white to nothing as Harlequin slid into financial trouble. Parts of the sys-
set, and so is also black with respect to it. tem are incomplete or have unclear status. A large amount of design
In practical terms, we work out the set of zones occupied by the documentation exists, but it is fairly disorganized and incomplete.
white set. We call this the interesting set. We can then make any We would like to organize all this information to make the MPS a
segment or root whose summary doesn’t intersect with the interest- more useful resource.
ing set black for the new trace. This is just a bitwise AND between The MPS was designed around many abstractions that make it
two machine words. A pool will usually arrange for a generation very adaptable, but it is not very well packaged and is unlikely to
to occupy a single zone, so this refinement step can eliminate a work in new applications without some modification. We would
like to improve the MPS to make it easier to apply without modifi- [1] American National Standards Institute. American National
cation. Standard for Information Systems: Programming Language
The MPS is currently commercially licensed to Global Graphics C, Dec. 1989.
Software Limited for use in the Harlequin RIP R , and to Configura [2] A. W. Appel, J. R. Ellis, and K. Li. Real-time concurrent
Sverige AB for use in their Configura R business system. We are collection on stock multiprocessors. ACM SIGPLAN Notices,
seeking further licensees and consultancy. 23(7):11–20, 1988.
[3] G. Attardi, T. Flagella, and P. Iglio. A customisable memory
8. AVAILABILITY management framework for C++. Software Practice and
Experience, 28(11):1143–1183, Nov. 1998.
The MPS project tree is available on the web at <http://
www.ravenbrook.com/project/mps/>. It includes all of [4] N. Barnes. MPS Format Protocol. MPS Project
the non-confidential source code and design documentation. This Documentation, November 2001.
is a mirror of the tree in Ravenbrook’s configuration management http://www.ravenbrook.com/project/mps/
master/mmdoc/protocol/mps/format/.
repository, so it will continue to reflect the development of the
MPS. [5] J. F. Bartlett. Mostly-Copying garbage collection picks up
generations and C++. Technical note, DEC Western
Research Laboratory, Palo Alto, CA, Oct. 1989. Sources
9. RELATED WORK available in ftp://gatekeeper.dec.com/pub/DEC/CCgc.
The MPS resembles the Customisable Memory Management (CMM) [6] H.-J. Boehm, A. J. Demers, and S. Shenker. Mostly parallel
framework for C++ [3] and shares some of its design goals. The garbage collection. ACM SIGPLAN Notices, 26(6):157–164,
MPS was not designed for C++, but as a memory manager for dy- 1991.
namic language run-time systems. In fact, it was specifically de- [7] H.-J. Boehm and M. Weiser. Garbage collection in an
signed not to require C++. uncooperative environment. Software Practice and
The Memory Management Reference Bibliography contains all Experience, 18(9):807–820, 1988.
the papers that we collected during the project, and can be found on [8] R. Brooksby. MM/EP-Core Requirements. MPS Project
the web at <http://www.memorymanagement.org/bib/>. Documentation (Confidential), November 1995.
[9] R. Brooksby. Allocation Buffers and Allocation Points. MPS
10. CONCLUSIONS Project Documentation, September 1996.
During our stay at Harlequin we were often frustrated by confi- http://www.ravenbrook.com/project/mps/
dentiality. We were not able to reveal ideas and techniques which master/mminfo/design/mps/buffer/.
we believed were both innovative and useful. The MPS contains [10] R. Brooksby. Dylan Requirements. MPS Project
many such ideas – the results of hard work by many people (see Documentation, October 1996.
11). Now, at last, we can reveal almost all. http://www.ravenbrook.com/project/mps/
The MPS is a highly portable, robust, extensible, and flexible master/mminfo/req/dylan/.
system for memory management, based on very powerful abstrac- [11] R. Brooksby. The architecture of the MPS. MPS Project
tions. It contains many more useful concepts and abstractions not Documentation, January 1997.
covered in this paper. http://www.ravenbrook.com/project/mps/
We hope that the ideas, techniques, and code of the MPS will master/mminfo/design/mps/arch/.
be useful. We also hope that companies will license the MPS or [12] CMMI Product Development Team. CMMISM for Systems
engage us to extend and develop it further. Engineering/Software Engineering, Version 1.02
(CMMI-SE/SW, V1.02) (Staged Representation). Technical
report, Software Engineering Institute, 2000.
11. ACKNOWLEDGEMENTS [13] E. W. Dijkstra, L. Lamport, A. J. Martin, C. S. Scholten, and
The authors would like to thank all the members of the Mem- E. F. M. Steffens. On-the-fly garbage collection: An exercise
ory Management Group for their contributions to the design and in cooperation. In Lecture Notes in Computer Science, No.
implementation of the MPS. 46. Springer-Verlag, New York, 1976.
The members of the Memory Management Group were: [14] R. K. Dybvig, C. Bruggeman, and D. Eby. Guardians in a
generation-based garbage collector. In Proceedings of
Name Period of membership
SIGPLAN’93 Conference on Programming Languages
Design and Implementation, volume 28(6) of ACM
Nick Barnes 1995-08/1997-11
SIGPLAN Notices, pages 207–216, Albuquerque, NM, June
Richard Brooksby 1994-02/1997-11
1993. ACM Press.
Nick “Sheep” Dalton 1997-04/1998-07
[15] T. Gilb and D. Graham. Software Inspection.
Lars Hansen 1998-06/1998-09
Addison-Wesley, 1995.
David Jones 1994-10/1999-06
Richard Kistruck 1998-02/1999-06 [16] H. Goguen, R. Brooksby, and R. M. Burstall. Memory
Tony Mann 1998-02/2000-02 management: An abstract formulation of incremental
Gavin Matthews 1996-08/1998-11 tracing. In Types for Proofs and Programs, International
David Moore 1995-04/1996-04 Workshop TYPES’99, pages 148–161. Springer, 2000.
Pekka P. Pirinen 1997-06/2001-04 [17] B. Hayes. Finalization of the collector interface. In
Richard Tucker 1996-10/1999-09 Y. Bekkers and J. Cohen, editors, Proceedings of
P. Tucker Withington 1994-02/1998-11 International Workshop on Memory Management, volume
637 of Lecture Notes in Computer Science, Stanford
12. REFERENCES
University, USA, 16–18 Sept. 1992. Springer-Verlag.
[18] D. A. Moon. Garbage collection in a large LISP system. In
G. L. Steele, editor, Conference Record of the 1984 ACM
Symposium on Lisp and Functional Programming, pages
235–245, Austin, TX, Aug. 1984. ACM Press.
[19] P. P. Pirinen. Barrier techniques for incremental tracing. In
R. Jones, editor, ISMM’98 Proceedings of the First
International Symposium on Memory Management, volume
34(3) of ACM SIGPLAN Notices, pages 20–25, Vancouver,
Oct. 1998. ACM Press. ISMM is the successor to the IWMM
series of workshops.
[20] D. M. Ungar. Generation scavenging: A non-disruptive high
performance storage reclamation algorithm. ACM SIGPLAN
Notices, 19(5):157–167, Apr. 1984. Also published as ACM
Software Engineering Notes 9, 3 (May 1984) — Proceedings
of the ACM/SIGSOFT/SIGPLAN Software Engineering
Symposium on Practical Software Development
Environments, 157–167, April 1984.