GC object finalization not guaranteed
Fawzi Mohamed
fmohamed at mac.com
Sat Apr 18 14:43:38 PDT 2009
On 2009-04-18 23:22:21 +0200, Leandro Lucarella <llucax at gmail.com> said:
> 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.
daemon theads are not joined
> 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
finalizer should not throw already now, if they do an exception is raised.
> 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 =)
More information about the Digitalmars-d
mailing list