GC object finalization not guaranteed

Leandro Lucarella llucax at gmail.com
Sat Apr 18 09:39:26 PDT 2009


Robert Jacques, el 18 de abril a las 11:56 me escribiste:
> On Sat, 18 Apr 2009 11:24:14 -0400, Leandro Lucarella <llucax at gmail.com> wrote:
> >I've just found out[1] this[2]:
> >
> >	The garbage collector is not guaranteed to run the destructor for
> >	all unreferenced objects.
> >
> >Is there any reason why D can't guarantee that all finalizers will be
> >called, at least when the program ends?
> 
> Well, a couple of quick tests show that under normal situations (i.e.
> normal program termination and termination from an exception) the
> finalizers do run (D2). However, if a finalizer throws an exception,
> then the rest of the finalizers aren't called. Also, if you call
> std.c.stdlib.exit, the finalizers won't run.

Well, I'm not talking about experimentation, I'm talking about source code
;)

The current GC implementation don't call finalizers for data that's still
reference when the program *ended* (this is allowed by the specs, so it's
fine, the question is why it's allowed by the specs).

Here is a simple example that demonstrate the case:

$ cat finalize.d

version (Tango)
	import tango.stdc.stdio;
else
	import std.c.stdio;

class A
{
	~this() { printf("term\n"); }
}

A a;

static this() { a = new A; }

void main()
{
	version (FREE)
		a = null;
}

$ for compiler in dmd dmd2 gdmd; do for version in '' '-version=FREE'; do $compiler $version finalize.d; echo $compiler $version; ./finalize; echo; done; done
dmd

dmd -version=FREE
term

dmd2

dmd2 -version=FREE
term

gdmd

gdmd -version=FREE
term

(I have my ldc copy broken right now, that's why I didn't test that
compiler ;)


This can happen behind your back too if some nice non-pointer value in the
stack or static data unfortunately is a valid pointer.

This example shows that:

$ cat finalize2.d 

version (Tango)
	import tango.stdc.stdio;
else
	import std.c.stdio;

class A
{
	~this() { printf("term\n"); }
}

size_t x;

void main()
{
	A a = new A;
	x = cast(size_t) cast(void*) a;
	version (FREE)
		x = 0;
}

(the results are the same as the previous example)


-- 
Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/
----------------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------------
- Que hacés, ratita?
- Espero un ratito...



More information about the Digitalmars-d mailing list