www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - DIP74 & GC Destructors

reply "rsw0x" <anonymous anonymous.com> writes:
Andrei mentioned work on reference counting recently so I'm 
assuming there's still plans on implementing DIP74¹.

With reference counted objects built into the language, it might 
be worth investigating dropping destructors from all non-RC'd GC 
allocated objects for a complete separation of objects that 
control resources and need finalization, and objects that do not.

The current destructor implementation is incredibly bug prone, 
and is often almost always misused. It has already been made 
quite clear that you _can not_ rely on the GC for releasing 
resources². The current GC is even non-reentrant³, meaning that 
you can't allocate in destructors. You also have to assume any 
other reference to heap-allocated memory is in an undefined state 
during a destructor, further limiting their usefulness.

Furthermore, not having to worry at all about destructors would 
improve the performance of the GC. The GC could just mark large 
blocks of memory as free without having to scan which blocks of 
memory have destructors, which can slow down sweeping(I have yet 
to do any sort of testing on this, it is just a theory.)

One of the main concerns when choosing D as a language is the GC 
performance, I think this is a well accepted fact. It's worth 
evaluating anything that might improve the performance of the GC 
in my opinion.

Bye.

¹ - http://wiki.dlang.org/DIP74
² - http://dlang.org/class.html#Destructor "... The garbage 
collector is not guaranteed to run the destructor for all 
unreferenced objects"
³ - 
http://dlang.org/phobos/core_exception.html#.InvalidMemoryOperationError
Jun 15 2015
parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
I hope we won't get builtin RC, but that's off-topic.

In any case, there has been talk about introducing finalizers 
instead of destructors for GC managed objects. 
rt_attachDisposeEvent() already exists and is used by std.signal 
for weak references, but it's a hack, it needs to be formalized.

These finalizers can then have much more restricted semantics 
than destructors, e.g. they must be callable on any thread, are 
generally un- safe if they access members with indirections, and 
so on.
Jun 15 2015
parent reply "rsw0x" <anonymous anonymous.com> writes:
On Monday, 15 June 2015 at 16:20:56 UTC, Marc Schütz wrote:
 I hope we won't get builtin RC, but that's off-topic.
I disagree, that's entirely on topic. I believe every modern implementation of Ada relies solely on RC(while having GC hooks.) Nobody really seems to have an issue with RC there. I personally believe that immediate RC and GC solve completely different issues of deterministic vs non-deterministic resource management. Trying to shoehorn them into the same thing gets you a broken, slow implementation(see: C++'s shared_ptr. It's dog slow and _way_ overused IMO.)
 In any case, there has been talk about introducing finalizers 
 instead of destructors for GC managed objects. 
 rt_attachDisposeEvent() already exists and is used by 
 std.signal for weak references, but it's a hack, it needs to be 
 formalized.

 These finalizers can then have much more restricted semantics 
 than destructors, e.g. they must be callable on any thread, are 
 generally un- safe if they access members with indirections, 
 and so on.
I'm honestly curious of examples where finalizers are needed. The one exception I can think of is managing non-GC objects, as in C#. But that *still* seems like a bad idea because there's zero guarantee the destructor will ever run - i.e, a GC implementation that decides to just never call destructors is a valid implementation. http://dlang.org/class.html#destructors "The garbage collector is not guaranteed to run the destructor for all unreferenced objects. " D has more than one issue here, from combining "finalizer" and "destructor" into the same term to destructors being incredibly bug-prone and almost useless as defined by the standard. I hope this gets looked at. Bye.
Jun 16 2015
parent "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Tuesday, 16 June 2015 at 15:48:18 UTC, rsw0x wrote:
 On Monday, 15 June 2015 at 16:20:56 UTC, Marc Schütz wrote:
 I hope we won't get builtin RC, but that's off-topic.
I disagree, that's entirely on topic. I believe every modern implementation of Ada relies solely on RC(while having GC hooks.) Nobody really seems to have an issue with RC there. I personally believe that immediate RC and GC solve completely different issues of deterministic vs non-deterministic resource management. Trying to shoehorn them into the same thing gets you a broken, slow implementation(see: C++'s shared_ptr. It's dog slow and _way_ overused IMO.)
Note that I'm all for supporting good RC, I'm just against adding special support for it _in the language_. Instead, the remaining obstacles for efficient and safe library-based RC should be solved, which from my POV mostly means implementing some version of the `scope` feature.
 In any case, there has been talk about introducing finalizers 
 instead of destructors for GC managed objects. 
 rt_attachDisposeEvent() already exists and is used by 
 std.signal for weak references, but it's a hack, it needs to 
 be formalized.

 These finalizers can then have much more restricted semantics 
 than destructors, e.g. they must be callable on any thread, 
 are generally un- safe if they access members with 
 indirections, and so on.
I'm honestly curious of examples where finalizers are needed.
Well, as I already mentioned, weak references, e.g. for a signal/slot mechanism, or for maintaining a cache that doesn't keep its contents alive. Apart from that, I don't see much use in them either. OTOH, weak references _are_ important, so there needs to be some mechanisms for implementing them. I guess finalizers are the easiest way to do it.
 The one exception I can think of is managing non-GC objects, as 
 in C#. But that *still* seems like a bad idea because there's 
 zero guarantee the destructor will ever run - i.e, a GC 
 implementation that decides to just never call destructors is a 
 valid implementation.
Agreed.
 http://dlang.org/class.html#destructors
 "The garbage collector is not guaranteed to run the destructor 
 for all unreferenced objects. "

 D has more than one issue here, from combining "finalizer" and 
 "destructor" into the same term to destructors being incredibly 
 bug-prone and almost useless as defined by the standard.

 I hope this gets looked at.
Agreed, too.
Jun 16 2015