Understanding the GC

Mike Parker aldacron at gmail.com
Wed Jan 30 00:15:14 PST 2013


On Wednesday, 30 January 2013 at 06:00:44 UTC, Jeremy DeHaan 
wrote:

>
> From what I understand, when an object is recovered by the GC, 
> the destructor may or may not be called. Why is that? Is it for

That's not quite correct. When the object is collected, its 
destructor will be called. But you have no control over when or 
if it will happen during runtime. More on this below in relation 
to your question about unreferenced objects.


> performace reasons? What about the destructors of objects that 
> the original object contained? Are they called when the item 
> finally get's taken care of by the GC, or when the object is 
> originally recovered by the GC?

Destructors of members will not be called when an object is 
collected. Only that of the object itself. But, there's no 
guarantee that any member references will still be valid when the 
object's destructor is called. See below for more.

>
> My other question is, at the end of the program will GC go 
> through every object it knows still holds memory and call their 
> destructors? My guess is that it does so that the GC ensures

Yes.

> all memory is successfully released before the program ends. I 
> just want to make sure since in http://dlang.org/class.html, it 
> says, "The garbage collector is not guaranteed to run the 
> destructor for all unreferenced objects." What exactly is an 
> unreferenced object?

A "referenced" object is one that is still in use by the program. 
Example:

auto mc = new MyClass;

// Here, there is exactly one reference to the MyClass instance
// and it is still active.

// But if i do this...
auto mc2 = mc;

// Now there are 2 references to the same instance.
// Set one to null.
mc = null;

// Now there is only one reference. Null it...
mc2 = null;

// Now all references to the original instance are invalid,
// so the object is unreachable by the program, so it is an
// unreferenced object.

The GC can only collect objects that it can be sure are 
unreferenced. Sometimes it can't be sure, in which case that 
particular object won't be collected during run time. For the 
objects that are determined to be collectable, there's no way to 
guarantee that any one of them will be collected in any given 
collection cycle. Because of that, you cannot rely on the order 
of destruction. Consider:

class Foo {}
class Bar { Foo f; }

Bar b = new Bar;
b.f = new Foo;

Given that b.f is the only reference to this Foo instance, then 
this instance of Foo will become unreferenced at the same time 
that the instance of Bar does. But, again, we cannot rely on the 
Bar instance being collected and destructed before the Foo 
instance. So if you have a Bar destructor that tries to access a 
member in f, then you would get a crash some of the time. Worse, 
what if there were more references to the Foo instance outside of 
Bar that haven't been released yet? If you tried to destroy f 
from the Bar destructor, or perhaps call some sort of cleanup 
method to release system resources that f controls, you'll get a 
crash somewhere else in the program when another bit of code 
tries to access the no longer valid reference. That would likely 
be a marathon debugging session, because most of the time you 
don't expect that sort of thing.

>
> Some other questions:
>
> At what point is the GC called to do it's thing while the 
> program is running? Is it at certain intervals or is it when 
> the program's memory reaches a certain point?

My understanding is that the current implementation only runs 
collections when memory is allocated. Meaning, when you allocate 
a new object instance, or cause memory to be allocated via some 
built-in operations (on arrays, for example), the GC will check 
if anything needs to be collected and will do it at that time. I 
don't know if it's run on every allocation, or only when certain 
criteria or met, and I really don't care. That's an 
implementation detail. The D language itself does not specify any 
of that.


More information about the Digitalmars-d-learn mailing list