Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Lost anonymous subs

by kappa (Chaplain)
on Dec 09, 2004 at 15:07 UTC ( [id://413566]=perlquestion: print w/replies, xml ) Need Help??

kappa has asked for the wisdom of the Perl Monks concerning the following question:

Hello, fellow monks!

Imagine this:

my @arr = (9) x 1000_000; my $code = sub { @arr }; undef $code;

The sub will create a local copy of @arr as it's really a closure not a simple sub. And as soon as the ref to the sub vanishes we lose ability to address that copy. Will it be garbage-collected? Anonymous subs cannot be GCed as far as I understand, the code is there forever, and what about the scratchpad (I may misuse the term) for copies of lexical vars?

Are there ways to creatively employ Devel::Size, Devel::Peek, B::LexInfo or some other module to get information on all currently allocated objects? The ps(1) is rather useless in this case because perl process may not return (on some systems it even cannot) the memory to the OS as soon as it's freed.

--kap

Replies are listed 'Best First'.
Re: Lost anonymous subs
by diotalevi (Canon) on Dec 09, 2004 at 15:15 UTC

    A template copy of your code remains because it is used when creating the value to be assigned to $code. That template does not contain a copy of @arr. Also, the value of $code is GCed. Also, when $code was assigned, it didn't recieve a copy - it got a pointer to the current binding of @arr at the time. That pointer is also GCed and if the value in @arr has no more references, it also is GCed.

    In short, your code will behave itself. The now unused memory will be known to the perl interpreter as unused memory and it is now up to perl about whether it will return it to the operating system or not. I'm fuzzy on this but I recall others saying that some operating systems (like Windows) allow perl to return memory and perhaps others don't allow perl to return the memory. In any case, if you were to need that memory for other data in your program, it would be re-used for whatever that new use was.

      Thanks for information! Things got clearer. And what about closure behaviour? The sub WILL need a copy of @arr, won't it? I cannot understand what «a pointer to the current binding of @arr» is, pardon my ignorance, the term is not in perlref or perlsub :(
      --kap
        This is all perl internals, perlguts stuff. The CV you get in $code has an ->OUTSIDE C pointer to the PADLIST that @arr lives in and then the compiled code has a note on which index in that PADLIST it is suppposed to access the @arr at. So it isn't a copy. The code in $code works with the real, original @arr, not a copy.
Re: Lost anonymous subs
by ikegami (Patriarch) on Dec 09, 2004 at 15:39 UTC

    No, @arr is still accessible:

    my @arr = (9) x 1000_000; my $code = sub { @arr }; undef $code; print(scalar(@arr), $/); # 1000000

    You might mean

    my $code; { my @arr = (9) x 1000_000; $code = sub { @arr }; } # @arr kept alive by the sub undef $code; # @arr freed print(scalar(@arr), $/); # error under strict.

    @arr would be freed at the undef. The memory is released to perl, but maybe not to the OS. There has been discussion on this in the past.

    Nit: perl uses reference counting, not garbage collection.

      I have written almost exactly the same piece of code in the reply to diotalevi up there because did not spot your comment. Yes, that helped me to understand things.

      I somehow got thinking that closures copy referenced lexicals when created. That was my error.

      This is the case when copying really takes place:

      my $Big = 'X' x 1000000; sub big { my $big = $Big; return sub { $big }; } my @crefs; push @crefs, big() for 1..10;
      --kap
        Well yes, that's because the = operator copies stuff. There's nothing special about that.
        Not exactly copy, more just steal. Usually lexicals hang around for the next time they go into scope (though they get reset to be empty/undef, they still hold memory). If you take a reference to one (including the case of a closure) and hold the reference until the lexical goes out of scope, the lexical has to get reallocated, since the remaining reference keeps the original.
      Nit Nit: perl uses reference counting to see what can be safely garbage collected AFAIK.
Re: Lost anonymous subs
by Joost (Canon) on Dec 09, 2004 at 17:54 UTC
    Will it be garbage-collected? Anonymous subs cannot be GCed as far as I understand.

    Unreferenced subroutines should be destroyed and garbage collected in perl (general caveats about circular references probably apply to subs too, I guess). IIRC there have been some problems in the past with memory leaks when removing subs (bugs in the perl interpreter: creating and destroying subs is valid and supported), so I just tested the following code in 5.8.5 and the process's memory use doesn't grow at all (it seems to be safe):

    #!/usr/local/bin/perl -w use strict; while (1) { my @arr = 'x' x 1000000; my $subref = sub { @arr; } }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://413566]
Approved by Limbic~Region
Front-paged by broquaint
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (8)
As of 2024-04-19 08:18 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found