Jump to page: 1 24  
Page
Thread overview
GC has a "barbaric" destroyng model, I think
Feb 11, 2015
Andrey Derzhavin
Feb 11, 2015
Orvid King
Feb 12, 2015
Jonathan M Davis
Feb 11, 2015
ketmar
Feb 12, 2015
Mike Parker
Feb 12, 2015
Kagamin
Feb 12, 2015
Jonathan M Davis
Feb 12, 2015
Kagamin
Feb 12, 2015
ketmar
Feb 12, 2015
ketmar
Feb 12, 2015
Paulo Pinto
Feb 12, 2015
ketmar
Feb 12, 2015
Andrey Derzhavin
Feb 12, 2015
Marc Schütz
Feb 12, 2015
Andrey Derzhavin
Feb 12, 2015
ketmar
Feb 12, 2015
Andrey Derzhavin
Feb 12, 2015
ketmar
Feb 12, 2015
Kagamin
Feb 12, 2015
Foo
Feb 13, 2015
Kagamin
Feb 13, 2015
Foo
Feb 13, 2015
Kagamin
Feb 13, 2015
Foo
Feb 13, 2015
Kagamin
Feb 12, 2015
ketmar
Feb 12, 2015
weaselcat
Feb 12, 2015
Mike Parker
Feb 12, 2015
ponce
Feb 12, 2015
Marc Schütz
Feb 12, 2015
ponce
Feb 12, 2015
ketmar
Feb 12, 2015
ponce
Feb 12, 2015
ketmar
Feb 12, 2015
Kagamin
February 11, 2015
       If we are using a DMD realization of destroying of objects, happens the following: at the calling the «destroy» method the calling of dtor takes place always, and then the object which is being destroyed is initialized by the default state. In other words, after calling «destroy» method, there is no way of getting an access to the members of the object that is being destroyed (it is meant, that the members are the references). GC works the same way.
	This approach in case of manual calling of «destroy» method has predictable and understandable consequences (there is no reasone to use the object being destroyed). But if GC performes the destroying of the objects, a lot of errors appear at the accessing to the members which are references, because some of them have already been destroyed (access to the members is realized in dtors). Such situations can be avoided, by using «@nogc» keyword. Howewer «@nogc» keyword doesn't protect us from using the references in dtors: we can assign some values to the refernces, we can have access to some members by the references and assign them some values.That is not correct in itself.

If GC starts destroying some group of the objects, it could be more correct, if the calls of dtros are occured of all objects in a group before phisical memory releasing. Or GC must call dtors of the objetcts only, which noone refers to.
February 11, 2015
On Wednesday, 11 February 2015 at 21:34:00 UTC, Andrey Derzhavin wrote:
>        If we are using a DMD realization of destroying of objects, happens the following: at the calling the «destroy» method the calling of dtor takes place always, and then the object which is being destroyed is initialized by the default state. In other words, after calling «destroy» method, there is no way of getting an access to the members of the object that is being destroyed (it is meant, that the members are the references). GC works the same way.
> 	This approach in case of manual calling of «destroy» method has predictable and understandable consequences (there is no reasone to use the object being destroyed). But if GC performes the destroying of the objects, a lot of errors appear at the accessing to the members which are references, because some of them have already been destroyed (access to the members is realized in dtors). Such situations can be avoided, by using «@nogc» keyword. Howewer «@nogc» keyword doesn't protect us from using the references in dtors: we can assign some values to the refernces, we can have access to some members by the references and assign them some values.That is not correct in itself.
>
> If GC starts destroying some group of the objects, it could be more correct, if the calls of dtros are occured of all objects in a group before phisical memory releasing. Or GC must call dtors of the objetcts only, which noone refers to.

The finalization order issue is one that is actually rather difficult, if not impossible, to solve without a precise GC. It gets even more complicated when you have to deal with cyclic references in finalizable allocations.
February 11, 2015
On Wed, 11 Feb 2015 21:33:59 +0000, Andrey Derzhavin wrote:

> If we are using a DMD realization of destroying of objects, happens the
> following: at the calling the «destroy» method the calling of dtor takes
> place always, and then the object which is being destroyed is
> initialized by the default state. In other words, after calling
> «destroy» method, there is no way of getting an access to the members of
> the object that is being destroyed (it is meant, that the members are
> the references). GC works the same way.
> 	This approach in case of manual calling of «destroy» method has
> predictable and understandable consequences (there is no reasone to use
> the object being destroyed). But if GC performes the destroying of the
> objects, a lot of errors appear at the accessing to the members which
> are references, because some of them have already been destroyed (access
> to the members is realized in dtors). Such situations can be avoided, by
> using «@nogc» keyword. Howewer «@nogc» keyword doesn't protect us from
> using the references in dtors: we can assign some values to the
> refernces, we can have access to some members by the references and
> assign them some values.That is not correct in itself.
> 
> If GC starts destroying some group of the objects, it could be more correct, if the calls of dtros are occured of all objects in a group before phisical memory releasing. Or GC must call dtors of the objetcts only, which noone refers to.

this problem has very easy solition: we should stop calling class dtors "destructors", and rename them to "finalizers".

The field is lost
Everything is lost
The black one has fallen from the sky and the towers in ruins lie

when finalizer is called, the battlefield is devastated, dead bodies lies everywhere, and so on. don't expect that those dead ones can still talk.

February 12, 2015
On Wednesday, February 11, 2015 21:40:30 Orvid King via Digitalmars-d-learn wrote:
> On Wednesday, 11 February 2015 at 21:34:00 UTC, Andrey Derzhavin wrote:
> >        If we are using a DMD realization of destroying of
> > objects, happens the following: at the calling the «destroy»
> > method the calling of dtor takes place always, and then the
> > object which is being destroyed is initialized by the default
> > state. In other words, after calling «destroy» method, there is
> > no way of getting an access to the members of the object that
> > is being destroyed (it is meant, that the members are the
> > references). GC works the same way.
> >     This approach in case of manual calling of «destroy» method
> > has predictable and understandable consequences (there is no
> > reasone to use the object being destroyed). But if GC performes
> > the destroying of the objects, a lot of errors appear at the
> > accessing to the members which are references, because some of
> > them have already been destroyed (access to the members is
> > realized in dtors). Such situations can be avoided, by using
> > «@nogc» keyword. Howewer «@nogc» keyword doesn't protect us
> > from using the references in dtors: we can assign some values
> > to the refernces, we can have access to some members by the
> > references and assign them some values.That is not correct in
> > itself.
> >
> > If GC starts destroying some group of the objects, it could be more correct, if the calls of dtros are occured of all objects in a group before phisical memory releasing. Or GC must call dtors of the objetcts only, which noone refers to.
>
> The finalization order issue is one that is actually rather difficult, if not impossible, to solve without a precise GC. It gets even more complicated when you have to deal with cyclic references in finalizable allocations.

Yeah. And what it comes down to is that you don't access anything on the GC heap from a class' finalizer, which seriously limits what you can do with them. And yes, that can suck, but there isn't an easy solution - especially when you take cyclical references into account. Basically, don't use class finalizers unless you have to, and even then, only use them to access stuff that isn't on the GC heap.

- Jonathan M Davis


February 12, 2015
On 2/12/2015 6:42 AM, ketmar wrote:

>
> this problem has very easy solition: we should stop calling class dtors
> "destructors", and rename them to "finalizers".
>

Absolutely. So many people coming from C++ see "destructor" and want to use them as they did in C++. How often do we see people coming on here wondering why they can't get deterministic destruction out of class destructors? Of course, it's too late to change anything now, but we need a big, obvious link from the docs and the wiki and anywhere else people can read about destructors to a page that explains how D class destructors are not C++ class destructors.

February 12, 2015
Truth be told, D has no guideline for deterministic destruction of managed resources.
February 12, 2015
On Thursday, February 12, 2015 08:33:34 Kagamin via Digitalmars-d-learn wrote:
> Truth be told, D has no guideline for deterministic destruction of managed resources.

Really what it comes down to is that if you want deterministic destruction, you _don't_ use managed resources. You use malloc and free rather than new and the GC. Granted, that's way uglier than it should be right now, because the allocator stuff hasn't been finished yet, but it's really what's required if you want an object on the heap to have a deterministic lifetime. Memory that's managed by a GC just doesn't work that way.

- Jonathan M Davis

February 12, 2015
On Thursday, 12 February 2015 at 08:14:49 UTC, Mike Parker wrote:
> On 2/12/2015 6:42 AM, ketmar wrote:
>
>>
>> this problem has very easy solition: we should stop calling class dtors
>> "destructors", and rename them to "finalizers".
>>
>
> Absolutely. So many people coming from C++ see "destructor" and want to use them as they did in C++. How often do we see people coming on here wondering why they can't get deterministic destruction out of class destructors? Of course, it's too late to change anything now, but we need a big, obvious link from the docs and the wiki and anywhere else people can read about destructors to a page that explains how D class destructors are not C++ class destructors.

http://p0nce.github.io/d-idioms/#The-trouble-with-class-destructors

I've also made one for "D can't do real-time because it has a stop-the-world GC"
http://p0nce.github.io/d-idioms/#The-impossible-real-time-thread

And one for "D doesn't have ADTs"
http://p0nce.github.io/d-idioms/#Recursive-Sum-Type-with-matching
February 12, 2015
On Thursday, 12 February 2015 at 08:33:35 UTC, Kagamin wrote:
> Truth be told, D has no guideline for deterministic destruction of managed resources.

+1

don't complain about people wondering why class destructors don't work when there's no _real_ way to do it in D beyond 'drop down to C level and get going.' D is absolutely horrid for resource management.
February 12, 2015
On Thursday, 12 February 2015 at 08:55:43 UTC, Jonathan M Davis wrote:
> On Thursday, February 12, 2015 08:33:34 Kagamin via Digitalmars-d-learn wrote:
>> Truth be told, D has no guideline for deterministic destruction
>> of managed resources.
>
> Really what it comes down to is that if you want deterministic destruction,
> you _don't_ use managed resources. You use malloc and free rather than new
> and the GC. Granted, that's way uglier than it should be right now, because
> the allocator stuff hasn't been finished yet, but it's really what's
> required if you want an object on the heap to have a deterministic lifetime.
> Memory that's managed by a GC just doesn't work that way.

That's a repetition of C++ atavism, that resource management == memory management. IStream is a traditional example of a GC-managed object, which needs deterministic destruction, and not because it consumes memory, but because it encapsulates an unmanaged resource, it has nothing to do with memory management, malloc and free.
« First   ‹ Prev
1 2 3 4