GC object finalization not guaranteed

Leandro Lucarella llucax at gmail.com
Sat Apr 18 14:22:21 PDT 2009


Leandro Lucarella, el 18 de abril a las 18:03 me escribiste:
> Fawzi Mohamed, el 18 de abril a las 22:48 me escribiste:
> > On 2009-04-18 22:25:32 +0200, Don <nospam at nospam.com> said:
> > 
> > >Leandro Lucarella wrote:
> > >>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?
> > 
> > when the main thread ends other threads might be running, and removing
> > memory they are using is not necessarily a good idea.
> 
> Then I guess gc_term() should be invoked when all threads have terminated.
> Is there any technical difficulty to do that?
> 
> > Exceptions might delay things indefinitely and allocate more memory.
> 
> Then I guess gc_term() should be invoked when all exceptions were
> processed. Is there any technical difficulty to do that?
> 
> I really didn't take a look at the compiler runtime stuff, so I don't
> really know how all that works.

Ok, this is the code that handle the D main (Tango runtime
compiler/ldc/rt/dmain2.d, main() function, around line 260):

    void runMain()
    {
        debug(PRINTF) printf("main runMain\n");
        result = main(args);
    }

    void runAll()
    {
        debug(PRINTF) printf("main runAll\n");
        gc_init();
        _moduleCtor();
        if (runModuleUnitTests())
            tryExec(&runMain);
        thread_joinAll();
        _d_isHalting = true;
        _moduleDtor();
        gc_term();
    }

    tryExec(&runAll);

    debug(PRINTF) printf("main dtor\n");
    _STD_critical_term();
    _STD_monitor_staticdtor();

    return result;

If thread_joinAll() is called before gc_term(), I can't see how a thread
could be still running when gc_term() is called. So, in terms of threads,
I don't see a problem here.

About exceptions, I think it could be solved too. One option is to require
gc_term() to be "nonthrow" (I mean, for D1 and D2). I think the specs
doesn't say anything about destructors throwing exceptions. I think they
shouldn't but let's suppose they could. Since there is no way the use can
catch a destructor exception thrown in the GC (well, not in an useful way,
one could try/catch the new call or something but that doesn't work for
concurrent collectors that can sweep in a separate thread anyway, so
I think it's a bad idea), I guess it would be acceptable to:
a) Ignore the exception
b) Let the user provide a callback to handle that kind of exceptions

Then, gc_term() ca be moved outside the tryExec(&runAll) call and
gc_term() can safely call all the live objects finalizers and provide
guaranteed finalization.


PS: I have not read all the runtime, just this small part, so maybe I'm
    missing the big picture =)

-- 
Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/
----------------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------------
PADRES DENUNCIAN QUE SU HIJA SE ESCAPO CON UN PARAGUAYITO
	-- Crónica TV



More information about the Digitalmars-d mailing list