Garbage collector collects live objects
Steven Schveighoffer via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Wed Mar 25 19:31:50 PDT 2015
On 3/25/15 9:51 AM, Ali Çehreli wrote:
> On 12/09/2014 08:53 AM, Steven Schveighoffer wrote:
>
> > On 12/9/14 11:17 AM, ketmar via Digitalmars-d-learn wrote:
>
> >> that file can be already finalized. please remember that `~this()` is
> >> more a finalizer than destructor, and it's called on *dead* object.
>
> Agreed: D has a terminology issue here, what we call a "class
> destructor" is a "class finalizer". I have added D to the Wikipedia
> article:
>
> http://en.wikipedia.org/wiki/Finalizer
>
> Now I want to improve some of my chapters.
>
> >> here this means that any other object in your object (including
> >> structs) can be already finalized at the time GC decides to call your
> >> finalizer.
>
> Although I know the fact above, I think ketmar makes a distinction (that
> is new to me) that a finalizer is a function that does not reference
> class members but a destructor does (or safely can).
Think of it this way -- a D destructor can access data from it's own
object. This means it CAN access its own members that are structs or
value types. It should NOT access referenced data, unless that data is
allocated outside the GC.
In Tango, there was a finalizer and a destructor. The finalizer was
called from the GC. The destructor was called when using the 'delete'
operator explicitly (and I think it also called the finalizer
afterward). Having this informational structure helps to know where to
put what cleanup code. I would love it if druntime added this feature,
or something similar.
>
> > File is specially designed (although it's not perfect) to be able to
> > close in the GC. Its ref-counted payload is placed on the C heap to
> > allow access during finalization.
> >
> > That being said, you actually don't need to write the above in the class
> > finalizer, _file's destructor will automatically be called.
> >
> >> just avoid "destructors" unless you *really* need that. in your case
> >> simply let GC finalize your File, don't try to help GC. this is not C++
> >> (or any other language without GC) and "destructors" aren't destructing
> >> anything at all. "destructors" must clean up the things that GC cannot
> >> (malloc()'ed memory, for example), and nothing else.
> >>
> >
> > Good advice ;)
> >
> > I would say other than library writers, nobody should ever write a class
> > dtor.
> >
> > -Steve
>
> Can somebody elaborate on that guideline please. Given a case where
> runtime polymorphism is needed, so that we have to use classes, does the
> guideline simply mean that "arrange for manual cleanup" or is there more
> in that guideline? I am confused about the "library writers" part. :)
Destructors should only be used to clean non-GC resources (and in terms
of completeness, you should implement such a destructor). It is
important to remember that the GC may NEVER get around to calling your
destructor. This means you cannot depend on it releasing non-GC
resources in a timely manner.
A good example is a file descriptor. If you have an object that contains
a file descriptor you SHOULD have a destructor which closes the file
descriptor if not already closed. However, you should NOT technically
rely on it being called in a timely manner. For cases where you can do
it synchronously, use a specific method to close the file descriptor.
There is a school of thought that says it is an error to rely on the GC
to destroy the FD, so why even have the destructor. But I see no reason
to leak the FD out of spite.
This is why I say it should be only library writers -- they are the ones
creating wrapper objects and using low level operations.
Of course, this isn't a hard and fast rule.
-Steve
More information about the Digitalmars-d-learn
mailing list