Raw File

		CMM: a Customisable Memory Manager

 Authors:	Giuseppe Attardi, Tito Flagella, Pietro Iglio
 Date:		26 October 95
 Address:	Giuseppe Attardi
		Dipartimento di Informatica
		Corso Italia 40
		I-56125 Pisa, Italy

 e-mail:	cmm@di.unipi.it


 | Table Of Contents

 - Overview
 - Installation
 - User Guide for C++
   -  DefaultHeap
   -  TempHeap
   -  MarkAndSweep
 - User Guide for C
 - Detecting Memory Leaks
 - Environment Variables
 - Reporting Bugs
 - Contributors

 | Overview

The CMM is a memory management facility supporting memory intensive
applications in C++.  The CMM can manage several heaps, each one implementing
a different storage discipline.  The default heap for collectable objects uses
the technique of mostly copying garbage collection, providing good performance
and memory compaction. Other available heaps are a temporary heap, and a
mark&sweep heap.

CMM users can define their own heap classes for the specific storage
requirements of their algorithms.

CMM has been tested on:

 - SunOS 4.x
 - Solaris 2.x
 - Linux 1.x
 - AIX (RS6000)
 - SGI

but it should run without changes also on HPUX, NeXTOS and DOS (djgpp).
If you are interest in some other platforms you can send mail to

 | Installation

The latest distribution of CMM is available via anonymous ftp from:


as a compressed (gzip) tar file.
Once you have obtained the distribution, you should extract its content
with the command:

	zcat cmm-XX.tar | tar xf -

This will create the directory 'cmm'.
Enter that directory and type:

	> make 

This will create a library file libCmm.a.

	> make test

will run a few test programs to test the library.

 | Quick Guide for C++

CMM provides two abstract classes, CmmHeap and CmmObject.
The available heaps are DefaultHeap, TempHeap, MarkAndSweep.
More complete documentation on the CMM is available in directory cmm/doc.
Programs using CMM must include the file cmm.h and link libCmm.a in the

When creating a collected object one can specify in which heap to
allocate it, by supplying a heap parameter to the new operator, e.g.:

   p = new(heap) Person(name, age);

If no heap parameter is supplied, the objects are allocated in the heap
specified by variable Cmm::heap, which by default has value


The DefaultHeap implements a mostly-copying collector: live objects are copied
and compacted except those pointed by ambiguous roots.

This approach is convenient for reducing fragmentation and swapping.
The drawback is that the user must supply information about the structure
of objects and the overhead for the copy.

Classes allocated in the DefaultHeap must be derived from class CmmObject.
A method traverse() must be supplied by the programmer for each such
collected class which contains pointers to other collected objects.
The collector applies method traverse() to an object to find other objects
to which it points.
See file cmm.h for details.


This heap is useful when a phase of a program allocates large amounts of
temporary objects which are discarded at the end of the phase.
A TempHeap is created with the instruction:

	tempHeap = new TempHeap(size);

At the beginning of the phase, the program can switch to the tempHeap
and clear it at the end of the phase, as follows:

  CmmHeap =previousHeap = CmmHeap::heap;  // save the current heap
  CmmHeap::heap = tempHeap;       // set the current heap to tempHeap
   ... program phase
  CmmHeap::heap = previousHeap;   // restore the previous heap
  ... copy out of tempHeap any object which must survive
  tempHeap->clear();              // empty the tempHeap


This collector is fully conservative, so there is no need to supply
information about objects layout. It does not perform compaction, therefore it
may be subject to fragmentation and it may retain more objects than necessary.

If you want automatic reclaimation for instances of a class `A' you must
declare `A' as a subclass of CmmObject. Read the CMM documentation for more

Once you declare class `A' as a subclass of CmmObject, every usage of new and
delete operators will automatically use the MSW memory manager.

No explicit initialization of the collector is needed and MSW_Automatic is
the default. You can override the default with a statement:

	Cmm::heap = new MarkAndSweep(MSW_OnDemand);

before using any other MSW function. The collector can be called explictly

This is the only way to activate the collector if you use the MSW_OnDemand
flag, otherwise the collector is automatically activated when the heap is

 | Quick Guide for C

Currently only the MarkAndSweep heap provides a C interface.
Since it is based on a fully conservative approach, there is no need to supply
information about the objects layout.

The "msw.h" file must be included at the top of every C file that uses the
allocator. The memory manager must be initialized. Such task is performed


before using any other function provided by MSW.

<type> can be:

 - MSW_Automatic (the collector is automatically invoked when needed)
 - MSW_OnDemand  (the collector is manually invoked by the user program) 

Once the collector has been initialized, you can use:

  void * mswAlloc   (size_t size);	       to allocate a memory object
  void   mswFree    (void * obj);	       to release a memory object
  void * mswRealloc (void * obj, size_t size); to resize a memory object

The behaviour of those functions is similar to the behaviour of malloc, free,
The main difference is that, while a memory object allocated with malloc()
can be only released calling free(), with MSW memory objects allocated with
mswAlloc() can also be reclaimed automatically. Explicit deallocation of
memory when no more need will delay the call to the collector when using
the MSW_Automatic flag.

For time-critical applications one can use:

	void * mswAllocOpaque (size_t size);

in the case you ensure that the allocated object will not contain pointers
inside (e.g. strings). This way such objects will not be traversed during the
collection, speeding-up the sweep phase and reducing the amount of ambigous
pointers traversed by the collector.

If the collector has been initialized with the MSW_Automatic flag, then
the collector is invoked automatically as soon the memory is low. It can 
also be called explicitly with:

	void 	mswCollect (void);

This is the only way to invoke the collector if MSW has been initialized with
the MSW_OnDemand flag.

 | Detecting Memory Leaks

MSW includes a useful memory leaks detector that checks internal heap
tables for corruption. You can enable memory leaks detection compiling
the MSW with the macro MSW_CHECK_HEAP defined and not defining the NDEBUG 

The heap is checked before and after every collection. You can place
explicit calls to the heap-checker in any `suspect' place using:


If <verbose> is not 0, then you will get some output when the heap is checked.

 | Environment Variables

Collector performance can be tuned using the following environment variables:

	CMM_MINHEAP	 initial heap size
	CMM_MAXHEAP	 maximum heap size
	CMM_INCHEAP	 increment size
	CMM_GENERATIONAL enable generational copying collector
	CMM_INCPERCENT	 expand threshold
	CMM_GCTHRESHOLD	 minimum amount of memory allocated before
			 the MarkAndSweep collector is called

Full description of these flags is in file cmm.h.

 | Reporting Bugs

Bugs, suggestions and comments can be sent to cmm@di.unipi.it.
When reporting a bug, please report the version number of the collector you
are using and - possibily - the complete source of the code showing the bug.

 | Contributors

The following people have contributed to this work:

Giuseppe Attardi, attardi@di.unipi.it
Tito Flagella,	tito@di.unipi.it
Pietro Iglio, iglio@di.unipi.it

Carlo Traverso and John Abbott contributed useful hints.
Joachim Hollman gave precious feedback on the first implementation of CMM.
back to top