Destructors vs. Finalizers
Steven Schveighoffer via Digitalmars-d
digitalmars-d at puremagic.com
Wed Jul 26 15:29:50 PDT 2017
On 7/26/17 12:01 PM, Guillaume Piolat wrote:
> On Wednesday, 26 July 2017 at 15:15:03 UTC, Steven Schveighoffer wrote:
>> On 7/26/17 10:57 AM, Guillaume Piolat wrote:
>>
>>> I'll defend the view point that there is _nothing_ useful to do in a
>>> finalizer except to check if the destructor has already been called.
>>
>> The thing to do in a finalizer that is useful is to release any non-GC
>> resources.
>
> Interesting case.
>
> Do we assume the finalizer is always called after the destructor?
Yes, finalizer and destructor should be called on deterministic
destruction (no need to repeat the finalizer code in the destructor).
> - If yes, then releasing these non-GC resources could have been possible
> in the destructor too. The only lost generality would be if releasing
> such non-GC resources would be faster from the GC thread (could well be
> since pooled).
But the destructor can't be called from the GC. In cases where the GC is
being used to clean up the object (whether on purpose or by accident),
then if you didn't have a finalizer, the resource leaks.
> - else, it's a case of the finalizer being calld by the GC and the
> destructor not being called. Is this considered a bug?
No.
> |
> | - If yes, then point of releasing resources is moot since we have a
> bug.
> |
> | - If not, it means we want to allow not calling destructors.
Of course, the idea is that a destructor does what the GC would have
done (recursively call the finalizers of members, and optionally clean
up memory if wholly owned).
> | |
> | | => this implies we think finalizers will be called
> | | I'll make claim this works for process-wide resources somehow
> (we stopped the last debate here), but not transient ones (eg: mutex)
> because of false pointers. The finalizer might be released late.
>
> From these premises I conclude that the instructions given to new D
> programmers would be:
>
> 1. you should destroy resources deterministically
>
> 2. however GC objects owning resources may release them in their
> finalizer
> * except if you can't release them from any thread
> * except if these resources should be released before the GC
> shutdown (and then you have to explain why finalizer might not be called
> right now).
Today, the finalizer is essentially a last-effort to clean up resources
that would otherwise leak.
The reason deterministic destruction sucks today is because once you go
2 levels deep, the only tool available (~this) cannot release any
resources (because it's not legal to access GC-allocated members inside
~this).
Adding a destructor concept would fix this issue, and make deterministic
destruction more pleasant.
Look at any library that contains such non-memory resources. These
things inevitably implement some sort of "close()" or "release()"
function, which does the deterministic destruction. It's just a
destructor with a different name.
-Steve
More information about the Digitalmars-d
mailing list