View mode: basic / threaded / horizontal-split · Log in · Help
May 24, 2012
Re: Destructor nonsense on dlang.org
On 24-05-2012 16:54, Andrei Alexandrescu wrote:
> On 5/24/12 9:28 AM, Alex Rønne Petersen wrote:
>> The GC should (and probably does) assume at shutdown that all objects
>> are unreferenced, and therefore reclaim and finalize them.
>
> They may refer to one another.
>
> Andrei
>

Doesn't matter: Nothing is guaranteed about order of finalization (and 
this is reasonable). Thus, the finalizers can be run in any arbitrary 
order. The important point here is that they are run *at all*.

-- 
Alex Rønne Petersen
alex@lycus.org
http://lycus.org
May 24, 2012
Re: Destructor nonsense on dlang.org
On 2012-05-24 16:53, Steven Schveighoffer wrote:

> What I think we need is a dispose pattern for objects, like Tango has.

Object.dispose in Tango is called on scope exit if the object is 
variable is declared "scope". "scope" is deprecated in D2.

-- 
/Jacob Carlborg
May 24, 2012
Re: Destructor nonsense on dlang.org
On Thu, 24 May 2012 11:04:06 -0400, Jacob Carlborg <doob@me.com> wrote:

> On 2012-05-24 16:53, Steven Schveighoffer wrote:
>
>> What I think we need is a dispose pattern for objects, like Tango has.
>
> Object.dispose in Tango is called on scope exit if the object is  
> variable is declared "scope". "scope" is deprecated in D2.
>

We can easily hook that in object.clear, which any scoped library  
implementation should be calling.

-Steve
May 24, 2012
Re: Destructor nonsense on dlang.org
On Thursday, 24 May 2012 at 15:04:06 UTC, Jacob Carlborg wrote:
> On 2012-05-24 16:53, Steven Schveighoffer wrote:
>> What I think we need is a dispose pattern for objects, like 
>> Tango has.
>
> Object.dispose in Tango is called on scope exit if the object 
> is variable is declared "scope". "scope" is deprecated in D2.

As for replicating that functionality, Scoped!T could always 
check for a magic dispose() method (maybe with another name, a 
marker parameter, …) and if it exists, call it on destruction.

But of course, the »universality« of the Tango runtimes 
solution is lost with this.

David
May 24, 2012
Re: Destructor nonsense on dlang.org
On 2012-05-24 14:35:45 +0000, Alex Rønne Petersen <alex@lycus.org> said:

> On 24-05-2012 14:43, Michel Fortin wrote:
>> I think it means that objects not collected when the program terminates
>> will never be, and thus the destructor will not be called.
> 
> That's silly. Microsoft .NET and Mono have been running finalizers on 
> runtime shutdown for a long time without problems.
> 
>> There's also the issue of false pointers that can prevent some objects
>> from being collected.
> 
> Right, but I think if we guarantee finalization at shutdown, that 
> shouldn't matter.

.NET is a virtual machine which has total control of all the code that 
runs. D has to work with the C runtime and other non-D code that might 
use D code more or less directly.

The interesting question is *how* do they do it without causing 
thread-safety issues? Perhaps they wait until all threads have been 
terminated, or perhaps they're unsafe too. Would doing the same be 
appropriate for D? Does this mean we can't use anything using static 
and global variables in destructors because they might have been 
finalized? If so, how does the compiler detects this?

If there's a way and it is not overly costly in performance, it might 
be a good idea. But we're not in a virtual machine, there are more 
constrains we must abide to and we might have to make different 
compromises.

Enlarging the scope of all this, there is already some impending 
problems with how destructors are handled in D that can easily create 
low-level races. And this applies to struct destructors too, when the 
struct is put on the heap or is a member of an object. We're in the 
need of a global solution for all this.

<http://d.puremagic.com/issues/show_bug.cgi?id=4621>
<http://d.puremagic.com/issues/show_bug.cgi?id=4624>


>> More generally, you can't really count on the destructor being called
>> because the GC is free to decide when to recycle memory. An
>> implementation that never collects and always allocate new memory is a
>> perfectly valid GC implementation, even though it might not be very
>> practical in most cases.
> 
> Even such an implementation should free all memory at shutdown, and, at 
> that point, run finalizers.

Well, not according to the current spec.

It could make sense to do so, although I'm not sure. Freeing "external" 
resources can mean many things: if we're talking about externally 
allocated memory, open files, sockets, mutexes, etc., there's no need 
to finalize that at the end of the program: the OS will do the cleanup 
for us. If we're talking about advisory locks on files, then there's 
definitely a need to clear the lock, although I'm not sure it makes 
sense to make the release dependent on a non-deterministic GC.

So I'm curious, what resource are we trying to free here?


-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/
May 24, 2012
Re: Destructor nonsense on dlang.org
Le 24/05/2012 15:49, Steven Schveighoffer a écrit :
> You actually need a finalizer if you want to have resources that aren't
> GC allocated.
>
> -Steve

Indeed. But java's way of doing it is very poor.
May 24, 2012
Re: Destructor nonsense on dlang.org
Le 24/05/2012 16:54, Andrei Alexandrescu a écrit :
> On 5/24/12 9:28 AM, Alex Rønne Petersen wrote:
>> The GC should (and probably does) assume at shutdown that all objects
>> are unreferenced, and therefore reclaim and finalize them.
>
> They may refer to one another.
>
> Andrei
>

So what ?

Each GC passes must, mark object that have to be removed, call finalizer 
on them all, THEN recycle memory.

So « zombie » object can still refer to one another in finalization.

The real problem is resurrection, which should be 100% forbiden and this 
must be enforced by the language (ie, the scopeness of this parameter is 
something important).
May 24, 2012
Re: Destructor nonsense on dlang.org
On 24-05-2012 17:18, Michel Fortin wrote:
> On 2012-05-24 14:35:45 +0000, Alex Rønne Petersen <alex@lycus.org> said:
>
>> On 24-05-2012 14:43, Michel Fortin wrote:
>>> I think it means that objects not collected when the program terminates
>>> will never be, and thus the destructor will not be called.
>>
>> That's silly. Microsoft .NET and Mono have been running finalizers on
>> runtime shutdown for a long time without problems.
>>
>>> There's also the issue of false pointers that can prevent some objects
>>> from being collected.
>>
>> Right, but I think if we guarantee finalization at shutdown, that
>> shouldn't matter.
>
> .NET is a virtual machine which has total control of all the code that
> runs. D has to work with the C runtime and other non-D code that might
> use D code more or less directly.

So does .NET. It just does it with some trampoline magic. Non-D code 
just has to call thread_attachThis()/thread_detachThis() and friends.

>
> The interesting question is *how* do they do it without causing
> thread-safety issues? Perhaps they wait until all threads have been
> terminated, or perhaps they're unsafe too. Would doing the same be
> appropriate for D? Does this mean we can't use anything using static and
> global variables in destructors because they might have been finalized?
> If so, how does the compiler detects this?

The CLR waits for all threads to have shut down (including daemon 
threads). That's not equal to all static/__gshared data being nulled 
out, mind you. All data is cleared out once all threads, including the 
finalizer thread, have been terminated one way or another.

And yes, it is thread safe.

>
> If there's a way and it is not overly costly in performance, it might be
> a good idea. But we're not in a virtual machine, there are more
> constrains we must abide to and we might have to make different
> compromises.

Don't need a virtual machine. We already have the infrastructure to do 
it in druntime, we just need to make the lifetime and GC code respect 
the C#/CLR finalization semantics if we want to go with those.

>
> Enlarging the scope of all this, there is already some impending
> problems with how destructors are handled in D that can easily create
> low-level races. And this applies to struct destructors too, when the
> struct is put on the heap or is a member of an object. We're in the need
> of a global solution for all this.
>
> <http://d.puremagic.com/issues/show_bug.cgi?id=4621>
> <http://d.puremagic.com/issues/show_bug.cgi?id=4624>
>
>
>>> More generally, you can't really count on the destructor being called
>>> because the GC is free to decide when to recycle memory. An
>>> implementation that never collects and always allocate new memory is a
>>> perfectly valid GC implementation, even though it might not be very
>>> practical in most cases.
>>
>> Even such an implementation should free all memory at shutdown, and,
>> at that point, run finalizers.
>
> Well, not according to the current spec.

No, but a sane implementation made for a sane spec should. ;)

>
> It could make sense to do so, although I'm not sure. Freeing "external"
> resources can mean many things: if we're talking about externally
> allocated memory, open files, sockets, mutexes, etc., there's no need to
> finalize that at the end of the program: the OS will do the cleanup for
> us. If we're talking about advisory locks on files, then there's
> definitely a need to clear the lock, although I'm not sure it makes
> sense to make the release dependent on a non-deterministic GC.

We just need a dispose pattern whereby explicit dispose() instructs the 
GC to not finalize.

>
> So I'm curious, what resource are we trying to free here?
>

None. I just came across it in the docs and found it completely insane.

-- 
Alex Rønne Petersen
alex@lycus.org
http://lycus.org
May 24, 2012
Re: Destructor nonsense on dlang.org
On Thursday, 24 May 2012 at 15:43:57 UTC, Alex Rønne Petersen 
wrote:
>
> We just need a dispose pattern whereby explicit dispose() 
> instructs the GC to not finalize.
>
>>
>> So I'm curious, what resource are we trying to free here?
>>
>
> None. I just came across it in the docs and found it completely 
> insane.

Hmm... well, as long as it's optional behavior... as in my case I 
actually want to go in the opposite direction... short-lived tool 
which claims x resources and is run once for every file...

So in this case, resources should be "free:ed" _unless_ it's at 
program termination... as then it just slows down the shutdown 
procedure, the OS reclaim it faster anyway.
May 24, 2012
Re: Destructor nonsense on dlang.org
On 5/24/12 9:57 AM, Alex Rønne Petersen wrote:
> On 24-05-2012 16:54, Andrei Alexandrescu wrote:
>> On 5/24/12 9:28 AM, Alex Rønne Petersen wrote:
>>> The GC should (and probably does) assume at shutdown that all objects
>>> are unreferenced, and therefore reclaim and finalize them.
>>
>> They may refer to one another.
>>
>> Andrei
>>
>
> Doesn't matter: Nothing is guaranteed about order of finalization (and
> this is reasonable). Thus, the finalizers can be run in any arbitrary
> order. The important point here is that they are run *at all*.

It does matter because a destructor may use an object that has just been 
destroyed.

Andrei
1 2 3 4 5 6 7
Top | Discussion index | About this forum | D home