Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

What the heck is: timely destruction

0 views
Skip to first unread message

K Stol

unread,
Aug 18, 2003, 1:52:50 PM8/18/03
to perl6-i...@perl.org
hello,

After reading most of the messages on timely destruction, I still don't quite understand what it is. If someone has a spare minute free, could you please explain?

Thanks in advance!

Klaas-Jan

Michael G Schwern

unread,
Aug 18, 2003, 5:04:09 AM8/18/03
to K Stol, perl6-i...@perl.org
On Mon, Aug 18, 2003 at 10:52:50AM -0700, K Stol wrote:
> After reading most of the messages on timely destruction, I still don't quite understand what it is. If someone has a spare minute free, could you please explain?

In perl5 you can write this.

my $Destroyed = 0;
sub DESTROY { $Destroyed = 1; }
{
my $object = bless {};
}
die unless $Destroyed;
print "That's timely destruction\n";

and expect it to work. It doesn't die and you reach the final print
statement. That's because object are destroyed *immediately* upon their
falling out of scope so you can trust that the DESTROY method is called
immediately following the block.

Other languages don't work this way. Java, for example, cleans up unused
objects whenever it happens to get around to it. This means your object
might be destroyed immediately, or after a few statements have run, or
stick around until the end of the program.

Timely destruction is simple in Perl5 because it has a simple garbage
collection scheme, reference counting. Each bit of date keeps track of how
many variables and references point to it. When it drops to 0, its cleaned
up. This count is kept up-to-date all the time so timely destruction
is easy.

Reference counting has problems. One is memory leaks due to circular
dependencies.

{ my $a;
my $b;
$a = \$b;
$b = \$a;
}

$a refers to $b. $b refers to $a. Their ref counts remain 1 even after
the block ends and their variables fall out of scope. The data is never
garbage collected. Memory leak.

Another is that it turns out to be pretty slow (last I heard Dan talk about
it) compared to modern garbage collecting techniques.

So Parrot is going with something else. Don't ask me what it is, I don't
know. With this other garbage collecting technique its more involved than
ref counting to guarantee timely destruction as we desire in Perl.
Apparently someone's figured a way to do it and do it efficiently.


--
Michael G Schwern sch...@pobox.com http://www.pobox.com/~schwern/

K Stol

unread,
Aug 18, 2003, 2:38:22 PM8/18/03
to Michael G Schwern, perl6-i...@perl.org

----- Original Message -----
From: "Michael G Schwern" <sch...@pobox.com>
To: "K Stol" <k...@home.nl>
Cc: <perl6-i...@perl.org>
Sent: Monday, August 18, 2003 2:04 AM
Subject: Re: What the heck is: timely destruction


> On Mon, Aug 18, 2003 at 10:52:50AM -0700, K Stol wrote:
> > After reading most of the messages on timely destruction, I still don't
quite understand what it is. If someone has a spare minute free, could you
please explain?
>
> In perl5 you can write this.
>
> my $Destroyed = 0;
> sub DESTROY { $Destroyed = 1; }
> {
> my $object = bless {};
> }
> die unless $Destroyed;
> print "That's timely destruction\n";
>
> and expect it to work. It doesn't die and you reach the final print
> statement. That's because object are destroyed *immediately* upon their
> falling out of scope so you can trust that the DESTROY method is called
> immediately following the block.
>
> Other languages don't work this way. Java, for example, cleans up unused
> objects whenever it happens to get around to it. This means your object
> might be destroyed immediately, or after a few statements have run, or
> stick around until the end of the program.
>

Thanks for your quick reply. I don't know perl and its behaviour that well,
so for my understanding, I'll summarize:

if I understood correctly, the problem is that some objects should be
destroyed *immediately*, and should not wait for the GC. In fact, the
programmer may have never heard about a garbage collecting system at all,
and just *assume* that everything which is out of scope, is destroyed. In
real life, these objects may live somewhere in memory, waiting for the GC,
but in fact are still there, so checking them for being alive will not yield
the correct result.

Is this summary correct?

Klaas-Jan


K Stol

unread,
Aug 18, 2003, 2:56:53 PM8/18/03
to Michael G Schwern, perl6-i...@perl.org

----- Original Message -----
From: "Michael G Schwern" <sch...@pobox.com>
To: "K Stol" <k...@home.nl>
Cc: <perl6-i...@perl.org>
Sent: Monday, August 18, 2003 2:49 AM
Subject: Re: What the heck is: timely destruction


> On Mon, Aug 18, 2003 at 11:38:22AM -0700, K Stol wrote:
> > if I understood correctly, the problem is that some objects should be
> > destroyed *immediately*, and should not wait for the GC.
>

> Yep. In perl 5 *all* objects and variables are to be destroyed
immediately.
> This doesn't necessarily mean that their memory has to be freed but that
> at least their destructor methods are called.


>
>
> > In fact, the programmer may have never heard about a garbage collecting
> > system at all, and just *assume* that everything which is out of scope,
> > is destroyed.
>

> Yep. That's how most languages with lexical variables work these days.


>
>
> > In real life, these objects may live somewhere in memory, waiting for
the GC,
> > but in fact are still there, so checking them for being alive will not
yield
> > the correct result.
>

> I don't understand what you're saying there.

Uhm, I didn't realize destructor methods were called, but now I see that's
the whole point:
destructor methods should be called when doing timely destruction.
You already said just now:

> This doesn't necessarily mean that their memory has to be freed but that
> at least their destructor methods are called.

So the objects may be still in memory. I thought the fact that they are
still in memory
was troublesome, but it's not, if I interpret your statement well.

Klaas-Jan


K Stol

unread,
Aug 18, 2003, 3:18:07 PM8/18/03
to Michael G Schwern, Elizabeth Mattijsen, perl6-i...@perl.org

----- Original Message -----
From: "Elizabeth Mattijsen" <l...@dijkmat.nl>
To: "K Stol" <k...@home.nl>; "Michael G Schwern" <sch...@pobox.com>
Cc: <perl6-i...@perl.org>
Sent: Monday, August 18, 2003 3:10 AM
Subject: Re: What the heck is: timely destruction


> At 11:56 -0700 8/18/03, K Stol wrote:
> >Uhm, I didn't realize destructor methods were called, but now I see
that's
> >the whole point:
> >destructor methods should be called when doing timely destruction.
> >You already said just now:
> >
> >> This doesn't necessarily mean that their memory has to be freed but
that
> >> at least their destructor methods are called.
> >
> >So the objects may be still in memory. I thought the fact that they are
> >still in memory
> >was troublesome, but it's not, if I interpret your statement well.
>

> No, the fact that a destructor method e.g. breaks the connection with
> a database server (that has a limited number of simultaneous
> connections) and is not called immediately and thus hogs resources
> that should be freed, is usually the problem. That somethiing that
> is known not to be in use anymore, is still in memory, is not a
> problem as it will be reclaimed automatically whenever more memory is
> needed.
>
>
Thanks for all your *fast* reactions. The problem is clear now.
It seems that these tasks of the GC system are quite
independent: calling destructors (doing clean-up tasks) and the actual
freeing the memory.

> Liz
>
Klaas-Jan


Michael G Schwern

unread,
Aug 18, 2003, 5:49:35 AM8/18/03
to K Stol, perl6-i...@perl.org
On Mon, Aug 18, 2003 at 11:38:22AM -0700, K Stol wrote:
> if I understood correctly, the problem is that some objects should be
> destroyed *immediately*, and should not wait for the GC.

Yep. In perl 5 *all* objects and variables are to be destroyed immediately.


This doesn't necessarily mean that their memory has to be freed but that
at least their destructor methods are called.

> In fact, the programmer may have never heard about a garbage collecting
> system at all, and just *assume* that everything which is out of scope,
> is destroyed.

Yep. That's how most languages with lexical variables work these days.


> In real life, these objects may live somewhere in memory, waiting for the GC,
> but in fact are still there, so checking them for being alive will not yield
> the correct result.

I don't understand what you're saying there.


It's Absinthe time!

Elizabeth Mattijsen

unread,
Aug 18, 2003, 6:10:50 AM8/18/03
to K Stol, Michael G Schwern, perl6-i...@perl.org
At 11:56 -0700 8/18/03, K Stol wrote:
>Uhm, I didn't realize destructor methods were called, but now I see that's
>the whole point:
>destructor methods should be called when doing timely destruction.
>You already said just now:
>
>> This doesn't necessarily mean that their memory has to be freed but that
>> at least their destructor methods are called.
>
>So the objects may be still in memory. I thought the fact that they are
>still in memory
>was troublesome, but it's not, if I interpret your statement well.

No, the fact that a destructor method e.g. breaks the connection with

a database server (that has a limited number of simultaneous
connections) and is not called immediately and thus hogs resources
that should be freed, is usually the problem. That somethiing that
is known not to be in use anymore, is still in memory, is not a
problem as it will be reclaimed automatically whenever more memory is
needed.


Liz

Michael G Schwern

unread,
Aug 18, 2003, 6:03:56 AM8/18/03
to K Stol, perl6-i...@perl.org
On Mon, Aug 18, 2003 at 11:56:53AM -0700, K Stol wrote:
> > This doesn't necessarily mean that their memory has to be freed but that
> > at least their destructor methods are called.
>
> So the objects may be still in memory. I thought the fact that they are
> still in memory
> was troublesome, but it's not, if I interpret your statement well.

I don't think its troublesome, no. From the PoV of the programmer, the
object has been destroyed. You can leave the freeing of memory for
later, that's an internal issue.

Beer still cheaper than crack!

Bennett Todd

unread,
Aug 18, 2003, 9:32:13 AM8/18/03
to perl6-i...@perl.org
2003-08-18T13:52:50 K Stol:

> After reading most of the messages on timely destruction, I still
> don't quite understand what it is. If someone has a spare minute
> free, could you please explain?

The other explanations certainly have formality to commend them, but
somehow they didn't make clear to me at least the real pungent
motivation.

Those of us who like timely destruction are fond of the fact that,
e.g.:

IO::File->new(">foo")->print("foo\n");
print `cat foo`;

will reliably and robustly print foo.

The IO::File handle, which was created and used in the first line,
ceases to have a reference to it as soon as that line as finished
executing, and so is immediately destroyed, which closes (and
therefore flushes) the output file.

There's about two decades of academic research whose intent was
to make garbage collection fast. Proponents of that work believe
that it's possible to have enough cleverness in the compiler to
(a) preserve timely destruction, while (b) running faster than
refcounting in the "interesting" cases (huge number of accesses to
data structures), (c) without unreasonable overhead in more typical
use, and (d) not requiring non-portable hardware support (e.g.
reaching into the hardware MMU, setting pages readonly, and catching
and servicing the access exceptions when writes are attempted to the
pages).

Is there really any such GC in existence anywhere?

-Bennett

Benjamin Goldberg

unread,
Aug 18, 2003, 7:58:49 PM8/18/03
to perl6-i...@perl.org, Michael G Schwern, K Stol
Michael G Schwern wrote:
[snip stuff, including a mention of refcounting and it's
(dis)advantages]

> So Parrot is going with something else. Don't ask me what it is, I
> don't know.

Parrot will do it like Java -- a mark-and-sweep garbage collector --
with the difference that garbage collection will generally happen more
often.

In Java, it happens when you run out of memory, or when someone does
"java.lang.Runtime.getRuntime().gc()". There's no timely destruction,
be cause you'd need to be psychic to know ahead of time when you're
going to run out of memory. And, since gc() isn't especially fast,
calling it often would slow your program down unnecessarily.

In Parrot, it happens when you run out of memory, or any time that a
"sweep" opcode is called. And "sweep" might be called at the end of
every scope, and maybe whenever you undef() a variable, and sometimes
even more often. Thus, chances to clean up objects in Parrot are almost
as frequent as they are in perl5.

> With this other garbage collecting technique its more involved than ref
> counting

Whether it's more involved or less involved depends on from whose point
of view you're looking.

From the POV of the person implementing the garbage collector, it's more
involved.

From the POV of the program using the system, it's less involved.

> to guarantee timely destruction as we desire in Perl. Apparently
> someone's figured a way to do it and do it efficiently.

Well... mostly.

As a memory manager, it's certainly more efficient. That is, if you
only call it when you need to free up memory, then on average, it uses
less time than refcounting does.

However, regarding the timely destruction part... this could use some
improvement.

Every time we come to a scope end, we do a garbage collection run. This
is often inefficient. We can sometimes statically determine that no
objects needing timely destruction could possibly have gone out of
scope, and leav out the "sweep" code.

But this still isn't enough.

What we'd like is a way (and there've been a couple proposed) to make it
so that the sweep at the end of scope can *quickly* determine that all
objects needing timely destruction are still alive/reachabe/in-scope,
and abort early (and thus use less time).

--
$a=24;split//,240513;s/\B/ => /for@@=qw(ac ab bc ba cb ca
);{push(@b,$a),($a-=6)^=1 for 2..$a/6x--$|;print "$@[$a%6
]\n";((6<=($a-=6))?$a+=$_[$a%6]-$a%6:($a=pop @b))&&redo;}

Leopold Toetsch

unread,
Aug 19, 2003, 3:20:40 AM8/19/03
to Benjamin Goldberg, perl6-i...@perl.org
Benjamin Goldberg <ben.go...@hotpop.com> wrote:

> Every time we come to a scope end, we do a garbage collection run.

... only if there are objects around, that were marked to need timely
destruction. If the HLL will decide that each object might need timely
destructions we will get into troubles, at least with the current DOD
scheme.

> What we'd like is a way (and there've been a couple proposed) to make it
> so that the sweep at the end of scope can *quickly* determine that all
> objects needing timely destruction are still alive/reachabe/in-scope,
> and abort early (and thus use less time).

Yes. Or that all such objects are destroyed already.

leo

Dave Whipp

unread,
Aug 18, 2003, 9:45:29 PM8/18/03
to perl6-i...@perl.org
"Benjamin Goldberg" <ben.go...@hotpop.com> wrote in message
news:3F416839...@hotpop.com...

> What we'd like is a way (and there've been a couple proposed) to make it
> so that the sweep at the end of scope can *quickly* determine that all
> objects needing timely destruction are still alive/reachabe/in-scope,
> and abort early (and thus use less time).

Just wondering: will these "quickly" methods also help solve the problem of
page thrashing on a process that runs out of physical RAM (and thus uses
virtual memory)? I've run into this problem on several GCed apps: the sweep
destroys locality of access, causing pages to be loaded that the application
doesn't need. This can cause a very abrupt performance drop.


Dave.


Leopold Toetsch

unread,
Aug 19, 2003, 7:29:31 AM8/19/03
to Dave Whipp, perl6-i...@perl.org
Dave Whipp <da...@whipp.name> wrote:

> ... I've run into this problem on several GCed apps: the sweep


> destroys locality of access, causing pages to be loaded that the application
> doesn't need. This can cause a very abrupt performance drop.

The flags used during DOD take (for simple PMCs) just one nibble. The
PMCs memory isn't pulled in any more. S. Juergen Boemmels update to

docs/memory_internals.pos
/ARENA_DOD_FLAGS

The collection phase is for sure cache unfriendly. The main problem is
string handling here. Reusing string headers and not generating new
strings all over the place improves on that very much.

> Dave.

leo

K Stol

unread,
Aug 19, 2003, 5:22:01 PM8/19/03
to l...@toetsch.at, Benjamin Goldberg, perl6-i...@perl.org
(Just another question concerning GC)

If I remember correctly, Java has a separate garbage collecting thread. I
though Parrot has
a synchronous garbage collector, right?
So, the garbage collector (or DoD for that matter) will run
in between execution of ops. If that is so, and DoD/GC is done on each scope
exit, then
that will slow down quite a bit, right? Or is that just my imagination?

Klaas-Jan

----- Original Message -----
From: "Leopold Toetsch" <l...@toetsch.at>
To: "Benjamin Goldberg" <ben.go...@hotpop.com>
Cc: <perl6-i...@perl.org>
Sent: Tuesday, August 19, 2003 12:20 AM
Subject: Re: What the heck is: timely destruction

Bennett Todd

unread,
Aug 19, 2003, 9:16:24 AM8/19/03
to perl6-i...@perl.org
Is the destruction going to be timely enough for

IO::File->new(">foo")->print("foo\n");
print `cat foo`;

to behave predictably?

-Bennett

Dan Sugalski

unread,
Aug 19, 2003, 8:43:28 AM8/19/03
to perl6-i...@perl.org

If you're asking if you can, in general, count on statement level timely
destruction of arbitrary objects, not by default, no. If you're asking
about this particular case, talk to Arthur, as it's perl 5. If you're
asking about the equivalent perl 6 version, then it depends on the default
impatience for IO::File handles. (Though I plan on having them *not* be
flagged as needing timely destruction. Larry may overrule, in which case
we'll fight over it)

Dan

Piers Cawley

unread,
Aug 19, 2003, 9:31:24 AM8/19/03
to Bennett Todd, perl6-i...@perl.org
Bennett Todd <b...@rahul.net> writes:

That's certainly the idea.

Luke Palmer

unread,
Aug 19, 2003, 11:19:08 AM8/19/03
to K Stol, l...@toetsch.at, Benjamin Goldberg, perl6-i...@perl.org
K Stol writes:
> (Just another question concerning GC)
>
> If I remember correctly, Java has a separate garbage collecting
> thread. I though Parrot has a synchronous garbage collector, right?
> So, the garbage collector (or DoD for that matter) will run in between
> execution of ops. If that is so, and DoD/GC is done on each scope
> exit, then that will slow down quite a bit, right? Or is that just my
> imagination?

That's what I'm worried about. In my code in particular, scopes go in
and out about half as much as statements do. That's why I want a really
efficient C<sweep 0>, and the reason for my proposal. I'd also like
Perl 6 to be smart enough to realize when I'm using "pure" functions and
have not changed anything that would affect DESTROY-able objects.

Luke

Steve Fink

unread,
Aug 24, 2003, 1:48:02 PM8/24/03
to K Stol, Michael G Schwern, perl6-i...@perl.org
It would probably make discussion easier if people switched to using
better terminology. I prefer using "destruction" to mean the memory
for an object actually getting freed, and "finalization" for whatever
cleanup actions an object performs at some point after it is no longer
accessible. So "timely destruction" is not very important, because
destruction only needs to be timely enough to avoid running out of
memory. "Timely finalization" is what we spend much time talking and
worrying about. In Perl5, if you didn't think about it too hard then
you could get away with thinking of them as being the same thing, even
though they never really were.

I guess you could think of the lifecycle of an individual object as
being controlled by a few significant life events:

1. birth
2. the last reference disappearing
3. finalization
4. destruction

Dan Sugalski

unread,
Aug 24, 2003, 2:36:35 PM8/24/03
to perl6-i...@perl.org
At 6:45 PM -0700 8/18/03, Dave Whipp wrote:
>"Benjamin Goldberg" <ben.go...@hotpop.com> wrote in message
>news:3F416839...@hotpop.com...
>> What we'd like is a way (and there've been a couple proposed) to make it
>> so that the sweep at the end of scope can *quickly* determine that all
>> objects needing timely destruction are still alive/reachabe/in-scope,
>> and abort early (and thus use less time).
>
>Just wondering: will these "quickly" methods also help solve the problem of
>page thrashing on a process that runs out of physical RAM (and thus uses
>virtual memory)?

This won't generally be an issue for Parrot, since the DOD sweep only
needs to look at PMCs, essentially just object headers, which are
allocated out of arenas. For swapout to be an issue you'd have to
have part or all of the arenas swapped out, which is pretty unlikely.
It may happen for objects which are alive and hold arrays of other
objects, but have been used rarely enough that they've swapped out,
but that's also unlikely. (Possible, though, certainly)

The current GC system, since it's a compacting collector, does have
the potential to touch a whole lot of pages, if you're unlucky enough
for your memory distribution to be such that there's one byte used
per swapped out page. That, bluntly, would suck. A lot. Not much for
it, though, as no matter what scheme you use you'll have that
problem. (Though other schemes can touch less memory, they have worse
performance characteristics in less-sparse situations, which are more
common)

While Parrot's DOD system's pretty heavily welded into the fabric of
the source, the GC bits aren't. If someone wants to do some
experimentation under different loads with different memory
allocators, go for it. I'm also happy to accept patches to decouple
the GC from the DOD more, as long as it doesn't impact current
performance, if you're not happy with the current decoupling.

NB: The DOD system finds dead objects. The GC system finds and
reclaims unused memory. Objects != memory, at least as far as
parrot's concerned. (Confusing or conflating the two will cause
issues, so don't :)
--
Dan

--------------------------------------"it's like this"-------------------
Dan Sugalski even samurai
d...@sidhe.org have teddy bears and even
teddy bears get drunk

Tim Bunce

unread,
Aug 24, 2003, 4:44:52 PM8/24/03
to Steve Fink, K Stol, Michael G Schwern, perl6-i...@perl.org

That's a nice idea, but I suspect most people are thinking in perl5
terms of "Timely DESTROY", so "destruction" is bound to be more
commonly used.

Tim.

Nicholas Clark

unread,
Aug 24, 2003, 5:03:27 PM8/24/03
to perl6-i...@perl.org

so you might want to use

1. birth
2. the last reference disappearing

3. (object) destruction
4. (memory) deallocation

which I believe is unambiguous.
And the "timely destruction" problem is about ensuring that nothing at
language level can spot a gap between steps 2 and 3.

It's unclear now which event really is the object's "death", and I can't see
any event corresponding to "taxes". :-)

Nicholas Clark

Steve Fink

unread,
Sep 5, 2003, 11:24:10 AM9/5/03
to Tim Bunce, K Stol, Michael G Schwern, perl6-i...@perl.org
Tim Bunce wrote:

I don't know -- in Perl5, the two are tied together so closely that it's
almost like naming the two halves of one thing: "DESTROY" becomes
"finalize,destroy". The decision to "destroy" is what triggers Perl5's
DESTROY invocation; Perl6 finalization is the body of the DESTROY
method. Never mind that they're out of order. :-)

Whichever. If you are aware of the difference, it's usually easy enough
to figure out which one people are talking about at any given moment
(and to recognize when they're confused about which one it is they're
talking about). I'm sticking to the "finalize" terminology, because
that's what I've seen used in non-perl5y contexts when they're
discussing exactly this issue. Since as you point out, "DESTROY" seems
stuck in people's heads, so I'll only suggest to people that changing
terminology might reduce the number of confused responses to their
posted ponderings.


0 new messages