Automatically reclaiming memory, known as garbage collection, is not a new
concept. Smalltalk and CLOS programmers know all about it, while Java
developers aren't far behind. In those languages, objects are freed
automatically when no references to them are left. But for developers using
more commonplace languages, garbage collection has not yet caught on.
Nothing, of course, comes for free. Developers know this all too well. This
truism accounts for some of the reluctance to embrace garbage collection
schemes in the past. In his book, The Design and Evolution of C++
(Addison-Wesley, 1994), Bjarne Stroustrup admits that garbage collection is
great if you can afford its run-time performance penalty. Since we've all been
nailed by pointer problems at one time or another, it doesn't take much to
appreciate the value of automatic memory reclamation, but at what cost? As
Stroustrup points out, service interruptions in serious, real-time applications
or in device drivers or operating system kernels are never acceptable.
The very idea of garbage collection may make you a little queasy, which is
quite understandable. Although the insidious nature of memory bugs makes
eradicating them a noble cause, using garbage collection to mop up unused
program memory is something with which most PC developers have little
familiarity. However, I'll briefly set aside the question of whether or not
automated memory recovery is a good idea.
The Proof Is in the Performance
Instead, I'll dive into how a new garbage collection tool, Geodesic Systems'
Great Circle, performs. Great Circle is a C and C++ library for Windows and
Solaris platforms that automatically handles garbage collection. With the Great
Circle library linked to your C or C++ program, you no longer have to be
concerned with freeing the memory you allocate. Conversely, you don't have to
worry about loose pointers from memory you released too soon. The garbage
collector handles it for you automatically. Great Circle accomplishes this by
replacing your compiler's memory allocator with its own. The difference is
pretty remarkable.
There's no fancy setup program, so installation is extremely simple. You
just copy the contents of three floppy diskettes to your hard drive. The
version I evaluated was designed for Microsoft Visual C++ 4.0, so I fired up
that development environment. True to its promise, I was able to use Great
Circle just by linking in one of its libraries, glib, to a project. With a
simple relink, the system was active and my program hummed along as usual. The
difference is that Great Circle redefined my calls to free() to do nothing. I
didn't need to make any changes to my existing code. For C++ programs, calls to
delete trigger an object's destructors (as usual) but do not free memory.
I wanted some kind of proof that the product was really doing something, so
rather than link in the glib library (the standard library you link in to
enable Great Circle), I used its gcreport library, which works like glib but
also outputs a log of what it has done. Using gcreport, you can see where
memory trouble spots are. You can even control how gcreport notifies you of
leaks by redefining its gcReportLeak function. For example, you could write a
different kind of log file, or direct the errors to an on-screen window.
Using Great Circle in this "leak detection" mode isn't really necessary, of
course, since the system automatically handles the leaks for you. Still, it's
gratifying to see and fix a problem with your program, nonetheless. The system
also comes with a debug version of the gcreport library that outputs additional
statistics about your program.
Choosing the Operating Mode
Great Circle has two operating modes: GCTransparent and GCPointers, and you
must choose one or the other. In GCTransparent mode, the system regularly scans
the stack, static segment, and registers to see if any 32-bit word could
possibly be considered a pointer to an allocated object if that value were
actually a pointer. If it finds a connection to an object, it marks it. At the
end of the scan, connections to allocated data that haven't been marked are
freed. This freeing is done in one fell swoop, as opposed to the multiple frees
found in programs without garbage collection. Geodesic Systems claims that this
can actually decrease the number of machine instructions executed over the long
run.
If you're not reassured by that claim, consider this: you can tell Great
Circle to perform minimal, incremental garbage collection; or you can tell it
to perform full garbage collection while your program is either running or
idle. For example, after displaying a screen full of data to browse, such as
that from a database table, you might want to let Great Circle perform garbage
collection.
Great Circle provides ways for you to customize its behavior. For example,
it allows C programmers to specify cleanup functions that can operate like a
destructor for a C++ class. This makes it possible to define what happens when
Great Circle automatically frees a specific structure, like one that has opened
a file or communications port. The finalization function, which would simply
close the file or port, is registered with Great Circle through a call to
gcDeclareFinalizer. In the call, you specify the object and the finalization
function name.
Unlike the transparent mode that requires just a relink to activate, the
GCPointers mode is more complex. With the complexity, however, comes more
control.
In GCPointers mode, you allocate memory using "smart pointers." Smart
pointers are classes whose constructors note the exact location of the pointers
in memory. Because of this, Great Circle does not need to scan to determine
memory usage as it does in GCTransparent mode. GCPointers is also the only mode
available if you want to use Great Circle with existing 16-bit code.
(GCTransparent works only with 32-bit programs.)
To use GCPointers, I had to change my class definitions to be derived from
Great Circle's gc class. Then I needed to make minor modifications to the
pointers to my classes in their declarations. Once changed, I could use the
pointers in the program without further changes to my code. The result was that
my class had its memory automatically managed. Even classes descended from my
class had their memory managed automatically.
Deciding which Great Circle mode to use is more than a question of how much
complexity you can tolerate. GCPointers mode is better suited for working with
all third-party memory management tools, and its performance is, according to
the company's statistics, faster than GCTransparent mode. On the other hand, I
really liked the easy way GCTransparent integrated with my current programs and
required no source changes for basic operations.
Configurable Memory Management
So, despite my positive results, you say you are not quite ready to turn
over your memory management scheme to an allocator you hardly know? Great
Circle apparently anticipated that too. You can choose to mix automatic and
traditional memory management whichever way you wish. I was able to tell the
system it was in full control, or that I only wanted it to handle specific
classes. This capability is essential, according to Stroustrup, since it allows
you to turn off the automated collection when you feel more comfortable
handling it on your own.
To configure the memory management of an application, use the gcsome library
in the GCTransparent mode. The gcsome library, when linked into a program, lets
you decide which memory you will manage and which memory Great Circle will
handle. Such a concession, however, requires some code changes. In C, it means
you must allocate memory with gcMalloc() if you want Great Circle to manage it.
In C++, you have to derive classes from the Great Circle class gc. Substituting
gcMalloc() for malloc() is normal behavior when C programs are linked with
gcall.
Great Circle is not without its nits. Despite its power, version 1.01 for
Windows does not support multithreaded programming, although multiple threads
are supported on the Solaris version. A beta copy of version 2.0 that arrived
late in my evaluation period does feature this support. The developers also
forecasted versions of Great Circle for OS/2, 16-bit DOS and Windows, 32-bit
Extended DOS, and some other UNIX workstations. The beta of version 2.0 scanned
memory allocated with LocalAlloc and GlobalAlloc, which were bypassed in this
shipping version (although there is a workaround).
Perhaps the most convenient enhancement to the forthcoming version 2.0,
however, is easier management of DLLs. With the new version, DLLs used by your
program are automatically garbage-collected by the system. With version 1.0,
DLLs have to be relinked with the product since Great Circle itself is a static
library, not a DLL. I was pleased to see that version 2.0 is almost as easy to
use as the first: instead of just adding a library to your makefile, you must
also include an .OBJ file. With those unintrusive changes, GCTransparent mode
will be up and running.
Code: Clean vs. Sloppy
Geodesic Systems claims that programmers spend more than 20% of their time
managing and debugging memory; and in large programs that figure can expand to
as much as 30% to 40%. If that's true, much of our time seems to be devoted to
the tricky art of properly balancing allocations and deallocations. No wonder
the theory of effective garbage collection has been with us for a while.
I won't lie and say that using Great Circle in its transparent mode stopped
me from coding calls to free() the way I always did. After all, old habits like
those are hard to break. And besides, I wanted to be sure my programs would
work if I didn't use Great Circle, or if someone else linked them and didn't
have Great Circle available. Nevertheless, the assurance of knowing my programs
were a lot less likely to suffer from occasional bouts with Software
Alzheimer's was quite comforting indeed. Language purists may argue that Great
Circle encourages coding sloppiness, but I don't agree. Used as another
powerful tool in your arsenal, Great Circle may hold the great promise of more
robust code with less head banging.
RATING: * * * *
|
The Rate Sheet |
Pros and Cons
PROS:
- Great Circle provides automated memory management and leak detection.
- The product operates transparently--it's very unobtrusive.
- You can control when collection cycles are performed.
CONS:
- Windows versions have no support for multiple threads(though the upcoming
version should correct this).
- Some memory operations aren't protected.
- DLLS must be relinked to be protected by Great Circle.
Company Information
Geodesic Systems Inc.
4745 North Ravenswood, Suite 111
Chicago, Ill. 60640
Tel: (800) 360-8388
Fax: (312) 728-6096
E-mail: [email protected]
Price: $495 on PC platforms; $1,095 on UNIX. No royalties.
Software Requirements: The Windows version requires either Microsoft
Visual C++ 2.x or 4.x, or Borland C++ 4.x. Versions 1 and 2 for Solaris require
any version of the Sparcworks or gpp compiler.
Hardware Requirements: No RAM requirement above what your compiler
requires. The Windows version requires 5MB of hard drive space. The
UNIXversion requires about 1MB.
Technical Support: One year of free support, including free upgrades, is
standard. Service plans are available subsequent to that.
Money-Back Policy: 90-day guarantee.
Circle #520 on Reader Service Card