Perl5.10.0ではクロージャをネストしたときのメモリリークが解消されているみたい

Perl5.8まではクロージャをネストした場合にメモリーリークが発生するという問題がありましたが、5.10.0では解消されているようです。

例えば以下のようなソースを実行すると

use strict;
use Devel::Leak::Object qw(GLOBAL_bless);
package Foo;
sub new {
        my $class = shift;
        return bless { id => shift }, $class;
}
sub DESTROY {
        my $self = shift;
        print "Destroy @{[$self->{id}]} $self\n";
}

package main;
sub main ($) {
        my $j = shift;
        print "# MAIN BLOCK START\n";
        my $foo = Foo->new( $j );
        sub {
                sub {
                        print "id = $foo->{id}\n"; # 二つ以上外のローカル変数を参照
                }->();
        }->();
        print "# MAIN BLOCK END\n";
}

print "Perl Version is $]\n";
main($_) for (1..3)

5.6だと$fooは解放されずにすべてリークしてしまいます。

実行結果

Perl Version is 5.006001
# MAIN BLOCK START
id = 1
# MAIN BLOCK END
# MAIN BLOCK START
id = 2
# MAIN BLOCK END
# MAIN BLOCK START
id = 3
# MAIN BLOCK END
After main
Tracked objects by class:
Foo                                      3
Destroy 2 Foo=HASH(0x8143074)
Destroy 3 Foo=HASH(0x8143158)
Destroy 1 Foo=HASH(0x80f5714)

l5.8だと一回目の$fooのみ解放されずに残ってしまいます。

Perl Version is 5.008008
# MAIN BLOCK START
id = 1
# MAIN BLOCK END
# MAIN BLOCK START
id = 2
# MAIN BLOCK END
Destroy 2 Foo=HASH(0x81c399c)
# MAIN BLOCK START
id = 3
# MAIN BLOCK END
Destroy 3 Foo=HASH(0x81c399c)
After main
Tracked objects by class:
Foo                                      1
Destroy 1 Foo=HASH(0x8152b44)

これが5.10.0で実行するとちゃんと期待通り動作するようになっていました。

Perl Version is 5.010000
# MAIN BLOCK START
id = 1
# MAIN BLOCK END
Destroy 1 Foo=HASH(0x8167f20)
# MAIN BLOCK START
id = 2
# MAIN BLOCK END
Destroy 2 Foo=HASH(0x8167f20)
# MAIN BLOCK START
id = 3
# MAIN BLOCK END
Destroy 3 Foo=HASH(0x8167f20)
After main
Tracked objects by class:

Errorモジュールのtry catchなどで暗黙にクロージャが生成される場合等注意が必要でしたが5.10.0だと安心して使用できそうです。