[Mono-devel-list] Limit Garbage Collection

Jonathan Pryor jonpryor at vt.edu
Tue Jul 19 06:59:48 EDT 2005


On Tue, 2005-07-19 at 12:22 +0200, Cedric Le Dressay wrote:
> .Net is an incredible step in the interroperability of languages. Nearly all 
> software developpements can use garbage collection. Unfortunately, some 
> others cannot like game developpement. Typically, a game cannot be 
> reasonnably freezed more than 20 ms (50 frames per second). Sometimes 
> requirements are even higher.

Some embedded systems use Java...

> Is there a way with mono to disable garbage collection and use the old 
> desalloc model?

With mono, you can set the GC_DONT_GC environment variable to disable
the GC.  This isn't ideal, as there is no way to explicitly free memory.
Result: memory leaks.  Lots of memory leaks...

> Is there a way to "cheat" and instead of really desollocating an objet of a 
> particuliar type to put it in a garbage list. This garbage list will be used 
> for the next allocation of the same type...

Do what the embedded Java developers do: ignore the GC.

The GC doesn't execute every N ms, it only executes when it runs out of
memory.  This is true for the generational/compacting GC .NET uses, the
Boehm GC Mono uses, and whatever Java uses.

Thus the simple solution: if you don't want the GC to run, don't
allocate any memory. :-)

This isn't quite as bad as it sounds.  You merely need to allocate your
object caches at the beginning of the program, and "create" and
"destroy" objects by using the object caches.  So instead of:

	MyType t = new MyType ();

you'd use:

	MyType t = MyType.Alloc ();
	/* ... */
	MyType.Free (t);

If you write your code carefully, once you've allocated all the object
caches and entered a steady-state, you shouldn't need to allocate any
additional memory, so the GC won't run any more.

The bad news is that object caches can harm performance (by scattering
object graphs across memory).

The .NET GC is a generational, compacting, GC.  Generation 1 is small
enough to fit inside the L1 processor cache.  Consequently, it can be
collected *very* quickly.  The compacting nature of the GC means that
anything that isn't garbage is compacted together, potentially resulting
in better memory locality of the remaining objects.

Result: instead of having objects potentially scattered across memory,
improving the costs of a cache miss and slowing down your program, the
GC allows objects allocated close to each other in time to be located
close to each other in (memory) space, improving cache and program
performance.

In other words, the creation of "garbage" might not be a bad thing. :-)

Alas, this is only true for .NET's GC.  Mono's Boehm GC is neither
generational nor compacting; it's rather like malloc(3)/free(3), with
some extra logic on top.  Thus, it won't get any such performance
improvements.

Summary: there are lots of trade-offs, and the presence of a GC is not
an automatic "bad thing".  You need to test your program and see if
there are any actual performance issues first.

 - Jon





More information about the Mono-devel-list mailing list