Blame doc/simple_example.html

Packit d28291
Packit d28291
<html lang="en-us">
Packit d28291
<HEAD>
Packit d28291
<meta http-equiv="Content-Type" content="text/html;charset=US-ASCII" >
Packit d28291
<TITLE>Using the Garbage Collector: A simple example</title>
Packit d28291
</head>
Packit d28291
<BODY>
Packit d28291

Using the Garbage Collector: A simple example

Packit d28291
The following consists of step-by-step instructions for building and
Packit d28291
using the collector.  We'll assume a Linux/gcc platform and
Packit d28291
a single-threaded application.  <FONT COLOR=green>The green
Packit d28291
text contains information about other platforms or scenarios.
Packit d28291
It can be skipped, especially on first reading</font>.
Packit d28291

Building the collector

Packit d28291
If you have not so yet, unpack the collector and enter
Packit d28291
the newly created directory with
Packit d28291
Packit d28291
tar xvfz gc<version>.tar.gz
Packit d28291
cd gc<version>
Packit d28291
Packit d28291

Packit d28291
You can configure, build, and install the collector in a private
Packit d28291
directory, say /home/xyz/gc, with the following commands:
Packit d28291
Packit d28291
./configure --prefix=/home/xyz/gc --disable-threads
Packit d28291
make
Packit d28291
make check
Packit d28291
make install
Packit d28291
Packit d28291
Here the "<TT>make check</tt>" command is optional, but highly recommended.
Packit d28291
It runs a basic correctness test which usually takes well under a minute.
Packit d28291

<FONT COLOR=green>Other platforms</font>

Packit d28291
<FONT COLOR=green>
Packit d28291
On non-Unix, non-Linux platforms, the collector is usually built by copying
Packit d28291
the appropriate makefile (see the platform-specific README in doc/README.xxx
Packit d28291
in the distribution) to the file "Makefile", and then typing "make"
Packit d28291
(or "nmake" or ...).  This builds the library in the source tree.  You may
Packit d28291
want to move it and the files in the include directory to a more convenient
Packit d28291
place.
Packit d28291
</font>
Packit d28291

Packit d28291
<FONT COLOR=green>
Packit d28291
If you use a makefile that does not require running a configure script,
Packit d28291
you should first look at the makefile, and adjust any options that are
Packit d28291
documented there.
Packit d28291
</font>
Packit d28291

Packit d28291
<FONT COLOR=green>
Packit d28291
If your platform provides a "make" utility, that is generally preferred
Packit d28291
to platform- and compiler- dependent "project" files.  (At least that is the
Packit d28291
strong preference of the would-be maintainer of those project files.)
Packit d28291
</font>
Packit d28291

<FONT COLOR=green>Threads</font>

Packit d28291
<FONT COLOR=green>
Packit d28291
If you need thread support, configure the collector with
Packit d28291
</font>
Packit d28291
Packit d28291
--enable-threads=posix --enable-parallel-mark
Packit d28291
Packit d28291
<FONT COLOR=green>
Packit d28291
instead of
Packit d28291
<TT>--disable-threads</tt>
Packit d28291
If your target is a real old-fashioned uniprocessor (no "hyperthreading",
Packit d28291
etc.) you will want to omit <TT>--enable-parallel-mark</tt>.
Packit d28291
</font>
Packit d28291

<FONT COLOR=green>C++</font>

Packit d28291
<FONT COLOR=green>
Packit d28291
You will need to include the C++ support, which unfortunately tends to
Packit d28291
be among the least portable parts of the collector, since it seems
Packit d28291
to rely on some corner cases of the language.  On Linux, it
Packit d28291
suffices to add <TT>--enable-cplusplus</tt> to the configure options.
Packit d28291
</font>
Packit d28291

Writing the program

Packit d28291
You will need a
Packit d28291
Packit d28291
#include "gc.h"
Packit d28291
Packit d28291
at the beginning of every file that allocates memory through the
Packit d28291
garbage collector.  Call <TT>GC_MALLOC</tt> wherever you would
Packit d28291
have call <TT>malloc</tt>.  This initializes memory to zero like
Packit d28291
<TT>calloc</tt>; there is no need to explicitly clear the
Packit d28291
result.
Packit d28291

Packit d28291
If you know that an object will not contain pointers to the
Packit d28291
garbage-collected heap, and you don't need it to be initialized,
Packit d28291
call <TT>GC_MALLOC_ATOMIC</tt> instead.
Packit d28291

Packit d28291
A function <TT>GC_FREE</tt> is provided but need not be called.
Packit d28291
For very small objects, your program will probably perform better if
Packit d28291
you do not call it, and let the collector do its job.
Packit d28291

Packit d28291
A <TT>GC_REALLOC</tt> function behaves like the C library <TT>realloc</tt>.
Packit d28291
It allocates uninitialized pointer-free memory if the original
Packit d28291
object was allocated that way.
Packit d28291

Packit d28291
The following program <TT>loop.c</tt> is a trivial example:
Packit d28291
Packit d28291
#include "gc.h"
Packit d28291
#include <assert.h>
Packit d28291
#include <stdio.h>
Packit d28291
Packit d28291
int main()
Packit d28291
{
Packit d28291
  int i;
Packit d28291
Packit d28291
  GC_INIT();
Packit d28291
  for (i = 0; i < 10000000; ++i)
Packit d28291
   {
Packit d28291
     int **p = (int **) GC_MALLOC(sizeof(int *));
Packit d28291
     int *q = (int *) GC_MALLOC_ATOMIC(sizeof(int));
Packit d28291
     assert(*p == 0);
Packit d28291
     *p = (int *) GC_REALLOC(q, 2 * sizeof(int));
Packit d28291
     if (i % 100000 == 0)
Packit d28291
       printf("Heap size = %d\n", GC_get_heap_size());
Packit d28291
   }
Packit d28291
  return 0;
Packit d28291
}
Packit d28291
Packit d28291

<FONT COLOR=green>Interaction with the system malloc</font>

Packit d28291
<FONT COLOR=green>
Packit d28291
It is usually best not to mix garbage-collected allocation with the system
Packit d28291
<TT>malloc-free</tt>.  If you do, you need to be careful not to store
Packit d28291
pointers to the garbage-collected heap in memory allocated with the system
Packit d28291
<TT>malloc</tt>.
Packit d28291
</font>
Packit d28291
Packit d28291

<FONT COLOR=green>Other Platforms</font>

Packit d28291
<FONT COLOR=green>
Packit d28291
On some other platforms it is necessary to call <TT>GC_INIT()</tt> from the main program,
Packit d28291
which is presumed to be part of the main executable, not a dynamic library.
Packit d28291
This can never hurt, and is thus generally good practice.
Packit d28291
</font>
Packit d28291
Packit d28291

<FONT COLOR=green>Threads</font>

Packit d28291
<FONT COLOR=green>
Packit d28291
For a multi-threaded program, some more rules apply:
Packit d28291
</font>
Packit d28291
    Packit d28291
  • Packit d28291
    <FONT COLOR=green>
    Packit d28291
    Files that either allocate through the GC or make thread-related calls
    Packit d28291
    should first define the macro <TT>GC_THREADS</tt>, and then
    Packit d28291
    include <TT>"gc.h"</tt>.  On some platforms this will redefine some
    Packit d28291
    threads primitives, e.g. to let the collector keep track of thread creation.
    Packit d28291
    </font>
    Packit d28291
    Packit d28291
    Packit d28291

    <FONT COLOR=green>C++</font>

    Packit d28291
    <FONT COLOR=green>
    Packit d28291
    In the case of C++, you need to be especially careful not to store pointers
    Packit d28291
    to the garbage-collected heap in areas that are not traced by the collector.
    Packit d28291
    The collector includes some alternate interfaces
    Packit d28291
    to make that easier.
    Packit d28291
    </font>
    Packit d28291
    Packit d28291

    <FONT COLOR=green>Debugging</font>

    Packit d28291
    <FONT COLOR=green>
    Packit d28291
    Additional debug checks can be performed by defining <TT>GC_DEBUG</tt> before
    Packit d28291
    including <TT>gc.h</tt>.  Additional options are available if the collector
    Packit d28291
    is also built with <TT>--enable-gc-debug</tt> (<TT>--enable-full-debug</tt> in
    Packit d28291
    some older versions) and all allocations are
    Packit d28291
    performed with <TT>GC_DEBUG</tt> defined.
    Packit d28291
    </font>
    Packit d28291
    Packit d28291

    <FONT COLOR=green>What if I can't rewrite/recompile my program?</font>

    Packit d28291
    <FONT COLOR=green>
    Packit d28291
    You may be able to build the collector with <TT>--enable-redirect-malloc</tt>
    Packit d28291
    and set the <TT>LD_PRELOAD</tt> environment variable to point to the resulting
    Packit d28291
    library, thus replacing the standard <TT>malloc</tt> with its garbage-collected
    Packit d28291
    counterpart.  This is rather platform dependent.  See the
    Packit d28291
    leak detection documentation for some more details.
    Packit d28291
    </font>
    Packit d28291
    Packit d28291

    Compiling and linking

    Packit d28291
    Packit d28291
    The above application <TT>loop.c</tt> test program can be compiled and linked
    Packit d28291
    with
    Packit d28291
    Packit d28291
    Packit d28291
    cc -I/home/xyz/gc/include loop.c /home/xyz/gc/lib/libgc.a -o loop
    Packit d28291
    Packit d28291
    Packit d28291
    The <TT>-I</tt> option directs the compiler to the right include
    Packit d28291
    directory.  In this case, we list the static library
    Packit d28291
    directly on the compile line; the dynamic library could have been
    Packit d28291
    used instead, provided we arranged for the dynamic loader to find
    Packit d28291
    it, e.g. by setting <TT>LD_LIBRARY_PATH</tt>.
    Packit d28291
    Packit d28291

    <FONT COLOR=green>Threads</font>

    Packit d28291
    <FONT COLOR=green>
    Packit d28291
    On pthread platforms, you will of course also have to link with
    Packit d28291
    <TT>-lpthread</tt>,
    Packit d28291
    and compile with any thread-safety options required by your compiler.
    Packit d28291
    On some platforms, you may also need to link with <TT>-ldl</tt>
    Packit d28291
    or <TT>-lrt</tt>.
    Packit d28291
    Looking at tools/threadlibs.c should give you the appropriate
    Packit d28291
    list if a plain <TT>-lpthread</tt> doesn't work.
    Packit d28291
    </font>
    Packit d28291
    Packit d28291

    Running the executable

    Packit d28291
    Packit d28291
    The executable can of course be run normally, e.g. by typing
    Packit d28291
    Packit d28291
    Packit d28291
    ./loop
    Packit d28291
    Packit d28291
    Packit d28291
    The operation of the collector is affected by a number of environment variables.
    Packit d28291
    For example, setting <TT>GC_PRINT_STATS</tt> produces some
    Packit d28291
    GC statistics on stdout.
    Packit d28291
    See <TT>README.environment</tt> in the distribution for details.
    Packit d28291
    </body>
    Packit d28291
    </html>