in reply to Lost anonymous subs

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.

Replies are listed 'Best First'.
Re^2: Lost anonymous subs
by kappa (Chaplain) on Dec 09, 2004 at 16:02 UTC

    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.
        my @abc; for my $m qw/a b c/ { push @abc, sub { $m }; } print $_->() . "\n" for @abc;
        No assignments and still, those subs each has its own $m. Or does the for my $m creates a new variable on each iteration?
        --kap
      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.
Re^2: Lost anonymous subs
by chb (Deacon) on Dec 10, 2004 at 08:55 UTC
    Nit Nit: perl uses reference counting to see what can be safely garbage collected AFAIK.