[gclist] memory leaks and the Boehm collector

Kragen Sitaker kragen@pobox.com
Wed, 14 Jul 1999 22:02:42 -0400 (EDT)


You write:
> My application is using the Boehm (et al) collector.
> Unfortunately, it is leaking memory :-(
> 
> The application in question is the Mercury compiler.
> It works fine if you compile one file at a time.
> But if you specify a lot of files on the command line,

Jones & Lins mention another program for which the Boehm collector had
this problem.

Since it's conservative, sometimes it thinks things are live that
aren't, if your program computes with large numbers or byte strings.
Depending on the way your data is linked together, this can be a minor
problem or it can totally vitiate the collector.

In particular, if your dead objects are a dense forest of cycles, then
even one false reference can keep huge amounts of stuff from being
freed.  Since the non-freed stuff is fertile ground for more false
references to spring up, this is a vicious cycle.

It seems like it ought to be able to mathematically determine some
degree of interlinkedness that will nearly ensure that this
chain-reaction leaking will happen.

If this is the problem, it might be possible to reduce or fix it:

- the Boehm collector allows you to declare large blocks of memory as
being pointer-free.
- I don't remember whether it allows you to request small pointer-free
objects, but if it does, you can split all your objects into
pointer-free and all-pointer parts, with the all-pointer part
containing a pointer to the pointer-free part.  Such a modification is
probably best done in the compiler (although it will result in a
non-ANSI-compliant compiler, since member offsets in structs will not
be constant, structs will not be contiguous, and creating structs on
the stack or in static memory or as part of other objects will result
in creating more heap objects).

Hmm, having read this, I'm not sure if I should send it -- particularly
since I have no actual experience with the Boehm collector.  I think it
is probably useful enough to send.

--
/* By Kragen Sitaker, http://pobox.com/~kragen/puzzle5.html */
char b[2000],m[]={1,-80,-1,80};main(){int i,x=1000,s=2000,d=0;while(1+(i=
getchar()))switch(i){case'f':b[x]=1;case'g':x=(x+m[d/2]+s)%s;d--;case'+':d+=2;
case'-':d+=7;d%=8;}for(i=0;i!=s;i++)putchar(" #"[b[i]]);}