Destructors and Deterministic Memory Management

Georg Wrede georg.wrede at iki.fi
Wed May 6 06:20:40 PDT 2009


Sean Kelly wrote:
> Georg Wrede wrote:
>> Sean Kelly wrote:
>>> dsimcha wrote:
>>>>
>>>> 1. It is often nice to be able to create a single object that
>>>> works with both GC and deterministic memory management. The
>>>> idea is that, if delete is called manually, all sub-objects
>>>> would be freed deterministically, but the object could still
>>>> safely be GC'd. Since the destructor called by the GC can't 
>>>> reference sub-objects, would it be feasible to have two
>>>> destructors for each class, one that is called when delete is
>>>> invoked manually and another that is called by the GC?

>>> You can do this today with both Druntime on D 2.0 and Tango on D 1.0, 
>>> though it isn't the most performant approach.  The code would look 
>>> something like this:
>>>
>>> import core.runtime;
>>>
>>> interface Disposable
>>> {
>>>     void dispose();
>>> }
>>>
>>> bool handler( Object o )
>>> {
>>>     auto d = cast(Disposable) o;
>>>
>>>     if( d !is null )
>>>     {
>>>         d.dispose();
>>>         return false;
>>>     }
>>>     return true;
>>> }
>>>
>>> static this()
>>> {
>>>     Runtime.collectHandler = &handler;
>>> }
>>>
>>> If you return false from your collectHandler then the runtime won't 
>>> call the object's dtor.
>>
>> Err, if one has an object that needs deterministic destruction, then 
>> one calls it (with say myDelete()) to have it release its resources. 
>> Until then, of course, it shouldn't get collected. But in any case it 
>> won't, because we obviously have a handler to it because we still 
>> haven't decided to destruct it. So I assume there's something I don't 
>> understand here.
>>
>> After we're done with destructing (as in having called myDelete()), 
>> then we "delete the object", or let it go out of scope. Then it 
>> becomes eligible for disposal. So, what's the relevance of Disposable 
>> here?
> 
> The collectHandler will only be called if an object is collected by the 
> GC, not if it's explicitly deleted.  So you could write the dtor in a 
> way that assumes all referenced subobjects are still valid and use 
> dispose for cleanup of garbage collected instances only.  To me that 
> sounded fairly close to what dsimcha was asking for.

Dsimcha wrote "Since the destructor called by the GC can't reference 
sub-objects", I got into thinking that we'd then need a myDestructor.

But

    delete myobject;

calls ~this() in myobject, as does the GC, as does program exit.

I also tested, and the referenced other objects did get deleted. No 
problem. That implies releasing other resources works, by simply having 
such release code in ~this() for the object.

I found no difference in calling delete or letting the GC do it. So, 
originally dsimcha's problem was imagined?



More information about the Digitalmars-d mailing list