Bug? GC collects memory that references itself.

Simen Kjaeraas simen.kjaras at gmail.com
Tue Oct 27 01:51:19 PDT 2009


Jeremie Pelletier <jeremiep at gmail.com> wrote:

> I need objects that may live without any references in GC memory, this  
> is for bindings to a C++ library. Using ranges or roots would be very  
> inneficient so my solution was to have the objects reference themselves  
> until the C++ side of the object calls a finalizer which nullify the  
> reference to let the GC collect the memory.
>
> The GC doesn't see things this way however, and collects the objects  
> even when they reference themselves.
>
> I've made a simple test program, the objects should never get collected.
>
> ---
>
> import core.memory;
> import std.stdio;
>
> class Foo {
> 	Foo self;
> 	this() { self = this; }
> 	~this() { assert(!self); }
> }
>
> void main() {
> 	foreach(i; 0 .. 50) new Foo;
> 	GC.collect();
> 	writeln("No object collected!");
> }
>
> ---
>
> If its a feature of the GC to prevent objects from never being  
> collected, how do I bypass it?

As Rayner pointed out, that's a cycle, and something the GC should ignore.
As for how to make it work:

class Foo {
     new( uint size ) {
         return malloc( size ); // Use good old malloc to allocate memory
     }

     delete( void* p ) {
         free( p ); // And free it with good old free.
     }
}

This is described under http://digitalmars.com/d/1.0/class.html#allocators
You might also need to use gc_addRoot to register the class with the GC,
and gc_removeRoot to unregister it upon deletion.

--
Simen


More information about the Digitalmars-d-learn mailing list