December 18, 2007 Re: GC does not delete subclass | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Matthias Thurau | Matthias Thurau wrote:
> "If the objects are no longer referenced, the GC will destroy those also."
>
> Thats exact the case: In my example the GC isn t destroying that unreferenced member.
I imagine Sean was correct when he said:
"I've noticed that the most recent object to be constructed is often not deleted in simple test cases. My guess is that a reference to this address is probably still lingering in a register somewhere, so the GC thinks it's still alive. This happens in Phobos and Tango."
In which case, yes, there is a 'bug' in full collect. Post a bug report, if one does not already exist. :)
Regan
| |||
December 18, 2007 Re: GC does not delete subclass | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Matthias Thurau | "Matthias Thurau" wrote
> "If the objects are no longer referenced, the GC will destroy those also."
>
> Thats exact the case: In my example the GC isn t destroying that unreferenced member.
My understanding of scope is that the object is supposed to be forcefully deleted at the end of the scope (not through the GC). So in your case, I believe there is a bug, because delete should call the destructor immediately. i.e.:
{
scope C = new C;
}
should be equivalent to:
{
auto C = new C;
delete C;
}
So I believe that the GC shouldn't be calling the destructor in fullcollect, it should be called BEFORE fullcollect is called.
Of course, I may be misunderstanding how scope works :)
With regards to my response, I just wanted to point out to Jason that destructors should not be used as he was alluding to.
-Steve
| |||
December 18, 2007 Re: GC does not delete subclass | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | Steven Schveighoffer Wrote:
> "Jason House" wrote
> > I haven't tried this, but is it possible to declare class member variables as scope so that they will get deleted when the rest of the object does? This could save coding of custom destructors in some cases.
>
> Custom destructors should NEVER destroy other GC allocated objects. the GC cannot guarantee the order of collection, meaning if you have a pointer to another GC allocated object, that object may have already been collected.
>
> There is no real reason to delete other objects in a destructor. If the objects are no longer referenced, the GC will destroy those also. The only things you should destroy in a destructor are non-GC allocated resources, such as file descriptors, or memory allocated with C's malloc.
>
> So to answer your question: scope is not necessary as a modifier for a member variable.
I wasn't asking about necessary. I was asking if it's valid. It's easy enough to construct RAII-like examples where a timely destruction of a member variable would be handy. It can also be handy when standard GC operation is overridden.
| |||
December 18, 2007 Re: GC does not delete subclass | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jason House | "Jason House" wrote > Steven Schveighoffer Wrote: > >> "Jason House" wrote >> > I haven't tried this, but is it possible to declare class member >> > variables >> > as scope so that they will get deleted when the rest of the object >> > does? >> > This could save coding of custom destructors in some cases. >> >> Custom destructors should NEVER destroy other GC allocated objects. the >> GC >> cannot guarantee the order of collection, meaning if you have a pointer >> to >> another GC allocated object, that object may have already been collected. >> >> There is no real reason to delete other objects in a destructor. If the >> objects are no longer referenced, the GC will destroy those also. The >> only >> things you should destroy in a destructor are non-GC allocated resources, >> such as file descriptors, or memory allocated with C's malloc. >> >> So to answer your question: scope is not necessary as a modifier for a member variable. > > I wasn't asking about necessary. I was asking if it's valid. It's easy enough to construct RAII-like examples where a timely destruction of a member variable would be handy. It can also be handy when standard GC operation is overridden. Not neccessary == not implemented :) Why implement a feature that is not needed? I guess I should have stated that. From the attributes page (http://www.digitalmars.com/d/attribute.html): "scope cannot be applied to globals, statics, data members, ref or out parameters." Timely destruction of a member that is not referenced in any other object/thread should occur when the object that owns the member is destroyed. No need to force it, which is why scope isn't necessary or valid. -Steve | |||
December 18, 2007 Re: GC does not delete subclass | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Matthias Thurau | Matthias Thurau wrote:
> "If the objects are no longer referenced, the GC will destroy those also."
>
> Thats exact the case: In my example the GC isn t destroying that unreferenced member.
Technically, it is. It's just not destroying it in the collection immediately following the object's allocation, which isn't guaranteed anyway. As I said previously, it's likely that a register still holds the address of this object when the allocation is triggered, because basically nothing happens between the object's construction and the collection. In a real application, such things are unlikely occur.
Sean
| |||
December 18, 2007 Re: GC does not delete subclass | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | Regan Heath wrote:
> I imagine Sean was correct when he said:
>
> "I've noticed that the most recent object to be constructed is often not deleted in simple test cases. My guess is that a reference to this address is probably still lingering in a register somewhere, so the GC thinks it's still alive. This happens in Phobos and Tango."
>
> In which case, yes, there is a 'bug' in full collect. Post a bug report, if one does not already exist. :)
Given that Sean is correct (which is plausible), then it is incorrect to
speak of a bug (or even a 'bug'). The algorithm works as specified.
If someone does not like (or understand) the specification you can hardly
(actually, not even remotely) speak of a bug.
Sorry for nitpicking, but this is bothering me.
regards, frank
| |||
December 18, 2007 Re: GC does not delete subclass | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | Steven Schveighoffer wrote:
> "Matthias Thurau" wrote
>> "If the objects are no longer referenced, the GC will destroy those also."
>>
>> Thats exact the case: In my example the GC isn t destroying that unreferenced member.
>
> My understanding of scope is that the object is supposed to be forcefully deleted at the end of the scope (not through the GC). So in your case, I believe there is a bug, because delete should call the destructor immediately. i.e.:
>
> {
> scope C = new C;
> }
>
> should be equivalent to:
>
> {
> auto C = new C;
> delete C;
> }
>
> So I believe that the GC shouldn't be calling the destructor in fullcollect, it should be called BEFORE fullcollect is called.
I'm pretty sure that this is what's happening. However, it is only deleting C, not the objects that C points to. This is necessary behavior. Consider:
class A
{}
class B
{
this( A a )
{
val = a;
}
A val;
}
void fn( A val )
{
scope B = new B( val );
}
You certainly wouldn't want the instance of A deleted when fn exits as well.
Sean
| |||
December 18, 2007 Re: GC does not delete subclass | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | "Sean Kelly" wrote
> I'm pretty sure that this is what's happening. However, it is only deleting C, not the objects that C points to. This is necessary behavior. Consider:
>
> class A
> {}
> class B
> {
> this( A a )
> {
> val = a;
> }
> A val;
> }
>
> void fn( A val )
> {
> scope B = new B( val );
> }
>
> You certainly wouldn't want the instance of A deleted when fn exits as well.
Oh! I misunderstood the original post.
Yes, I agree that the current behavior should be the expected behavior for the original example.
I thought that for some reason the destructor of the scoped class was not getting called when the scope exited.
-Steve
| |||
December 18, 2007 Re: GC does not delete subclass | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | On Tue, 18 Dec 2007 11:45:49 -0800, Sean Kelly <sean@f4.ca> wrote: >Matthias Thurau wrote: >> "If the objects are no longer referenced, the GC will destroy those also." >> >> Thats exact the case: In my example the GC isn t destroying that unreferenced member. > >Technically, it is. It's just not destroying it in the collection immediately following the object's allocation, which isn't guaranteed anyway. As I said previously, it's likely that a register still holds the address of this object when the allocation is triggered, because basically nothing happens between the object's construction and the collection. In a real application, such things are unlikely occur. > > > ~this() { writefln("Destructor %d", myNumber); } To help the GC, is Java-like null assignment necessary? The following line helps std.gc.fullCollect() to destroy My2Class members. ~this() { writefln("Destructor %d", myNumber); member = null; } Gide | |||
December 19, 2007 Re: GC does not delete subclass | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Gide Nwawudu | Gide Nwawudu wrote:
> On Tue, 18 Dec 2007 11:45:49 -0800, Sean Kelly <sean@f4.ca> wrote:
>
>> Matthias Thurau wrote:
>>> "If the objects are no longer referenced, the GC will destroy those also."
>>>
>>> Thats exact the case: In my example the GC isn t destroying that unreferenced member.
>> Technically, it is. It's just not destroying it in the collection immediately following the object's allocation, which isn't guaranteed anyway. As I said previously, it's likely that a register still holds the address of this object when the allocation is triggered, because basically nothing happens between the object's construction and the collection. In a real application, such things are unlikely occur.
>>
>>
>
>> ~this() { writefln("Destructor %d", myNumber); }
>
> To help the GC, is Java-like null assignment necessary? The following
> line helps std.gc.fullCollect() to destroy My2Class members.
>
> ~this() { writefln("Destructor %d", myNumber); member = null; }
Not usually. The problem is this case is a register with the value, not a memory location. I've run into it before when trying to create simple unit tests and demos in D. The easiest way around it that I've found is to construct an additional "throw away" object after the object you expect to be cleaned up, to overwrite any lingering register data that may still point to the old object. This is handy for tiny test apps, but again, I don't think anything needs to be done for real apps.
Sean
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply