Tree [r7] /

File Date Author Commit
COPYING 2010-10-14 meixner [r1] Initial version
COPYING.LESSER 2010-10-14 meixner [r1] Initial version
Changelog 2014-04-07 meixner [r6] Bug fixes for 64 bit systems
Makefile 2014-04-07 meixner [r7] Speed/memory optimization
README 2014-04-05 meixner [r5] Version 0.4: fixed compiling issues on x86-64
example.cxx 2010-10-24 meixner [r2]
gc_ptr.cxx 2014-04-07 meixner [r7] Speed/memory optimization
gc_ptr.h 2010-10-26 meixner [r3] __attribute__((noinline)) is not required any m...
gc_test.cxx 2010-10-24 meixner [r2]

Read Me

                              Version 0.4
                Copyright (C) 2010 Dr. Matthias Meixner

    MeixnerGC is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    MeixnerGC is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with MeixnerGC.  If not, see <>.

MeixnerGC provides the smart pointer class gc_ptr for C++ implementing 
an incremental mark and sweep garbage collector. 

Due to the use of mark and sweep it can garbage collect cycles which is not 
the case with most other smart pointer implementations.

It can be used to garbage collect all types of objects, they do not have to
be prepared (e.g. by providing special member functions) to be collected by 
the garbage collector. The garbage collector just calls the standard destructor 
of the object. 

Unlike most other smart pointer implementations gc_ptr is meant to be a 
complete replacement of plain pointers. Therefore, it supports pointer
arithmetic and may safely be used to point to anything, e.g. data on stack
or global data. Also the difference between single objects and arrays
is handled and the correct deallocation functions called.

MeixnerGC overloads the global new and delete operators to track
memory allocations. Therefore, it cannot be used with software that is also
overloading these global operators. 
The multi-threading version requires POSIX threads.

"make" will create two shared libraries:

 -     - library for single-threaded applications
 -  - library for multi-threaded applications

Both implement the same interface defined by gc_ptr.h

When compiling a program using these libraries make sure that they can be
found in the library search path.

"make unittest" will run some tests to check whether the library is working
correct with your version of the compiler.

For using the garbage collector two things have to be fulfilled: The memory
must be allocated using "new(gc)" instead of using "new". This marks the
memory to be considered for garbage collection. Memory allocated using "new"
or pointers obtained by any other way (e.g. by taking the address from an
object on the stack) are not touched by the garbage collector. Therefore, it
is safe to use gc_ptr for any kind of pointers.
Up to this point memory is marked to be managed by the garbage collector but
it is not yet actively managed since no smart pointer is pointing to it yet.
The management by the garbage collector is activated by assigning the newly
allocated object to gc_ptr. On first contact with gc_ptr as much type
information is extracted as possible to be able to call the "correct"
destructor for this object. Therefore, the type must not be disguised to
gc_ptr or the wrong destructor may be called. 

The following example shows how gc_ptr and the garbage collector should be

#include <vector>
#include <assert.h>
#include "gc_ptr.h"

class B { public: virtual ~B() {} int a; };

class A: public B { public: virtual ~A() {} int b; };

int main()
   gc_ptr<A> a=new(gc) A;  // allocate object
   gc_ptr<B> b=new(gc) A;  // OK, since type is visible to gc_ptr
   b=(B *)new(gc) A;       // Error, type is disguised and not visible to b
   a=new(gc) A[10];        // OK, gc_ptr can handle arrays, too
   a=(new(gc) A[10])+1;    // Error, on first contact the pointer must not
                           // have been modified   

   A local;
   a=&local;               // OK, gc_ptr may point to anything
   std::vector<A> v(10);
   a=&v[2];                // OK, the memory inside vector is not released
                           // as it has not been allocated using new(gc)
                           // and is handled by vector
   a=cast_gc_ptr<A>(b);               // replacement for C-style casts
   a=static_cast_gc_ptr<A>(b);        // replacement for static_cast
   a=reinterpret_cast_gc_ptr<A>(b);   // replacement for reinterpret_cast
   a=dynamic_cast_gc_ptr<A>(b);       // replacement for dynamic_cast

   gc_ptr<const B> b2=b;
   b=const_cast_gc_ptr<B>(b2);        // replacement for const_cast

   b=new(gc) B;


More usage examples can be found in the unit test gc_test.cxx and gc_test_mt.cxx

Cast operators
For proper casting replacement functions have been created. These are:
  - cast_gc_ptr<>()           
  - static_cast_gc_ptr<>()
  - reinterpret_cast_gc_ptr<>()
  - dynamic_cast_gc_ptr<>()
These should be used over the C++ cast operators to achieve better type
checking. E.g. you should use
instead of 
   static_cast<gc_ptr<A> >

GC Interface
In addition to the smart pointer gc_ptr the following two functions are 

int gc_collect()

   This perform a single garbage collection step. It returns 1 each time 
   when the end of the garbage collection cycle has been reached.
   This function is internally used by new(gc) to run the garbage collector.

void gc_collect_all()

   This runs the garbage collector until all non-reachable objects 
   have been released.

Internal operation
On construction gc_ptr objects check if they live within the global data
section, on stack or within allocated memory and register themselves
accordingly. At the same time it keeps track of all allocated memory.
The garbage collector uses this information to determine the root set
of pointers. Starting with these pointers the garbage collector marks
all memory that can be reached. In the end all garbage collectable memory
that has not been marked is released.
The garbage collector operates incrementally, on each allocation only 
a subset of objects is inspected by the garbage collector.