Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

Great Circle 1.01


August 1996: Great Circle 1.01

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:

  1. Great Circle provides automated memory management and leak detection.

  2. The product operates transparently--it's very unobtrusive.

  3. You can control when collection cycles are performed.

CONS:

  1. Windows versions have no support for multiple threads(though the upcoming

    version should correct this).

  2. Some memory operations aren't protected.

  3. 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]

Web: http://www.geodesic.com


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


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.