什么时候匿名数组/哈希会在perl中被垃圾收集?

com*_*fan 2 perl garbage-collection

我知道perl无法检测到递归引用:

$a = \$a;
Run Code Online (Sandbox Code Playgroud)

$a 在这种情况下永远不会被GC.

关于什么 :

@a = ({1,2,3}, [1,2,3]);
Run Code Online (Sandbox Code Playgroud)

是否会匿名{1,2,3}[1,2,3]@a超出范围时被收集?

如何证明是或否?

ike*_*ami 6

如果@a = ({1,2,3}, [1,2,3]);超出范围,它的引用计数将减少一个*.

当引用计数@a达到零时,其值的引用计数将减1,并将被释放.

当引用计数$a[0](对散列的引用)达到零时,引用的散列的引用计数将减1,并且将被释放.

当匿名散列的引用计数达到零时,其值的引用计数将减1,并将被释放.

当其中一个匿名散列值的引用计数达到零时,其值的引用计数将减1,并将被释放.

同样适用$a[1]于它引用的数组和该数组的值.

您可以通过使用具有析构函数的对象来"证明"这一点.

$ perl -E'
   package X {
      sub new { my ($c,$n) = @_; bless(\$n, $c) }
      DESTROY { say ${$_[0]}; }
   }
   {
      my @a = (
         { a => X->new(1), b => X->new(2) },
         [ X->new(3), X->new(4) ],
      );
      say "Before end of scope";
   }
   say "After end of scope";
'
Before end of scope
4
3
2
1
After end of scope
Run Code Online (Sandbox Code Playgroud)

* - 实际实施因优化而异.