Garbage collection in Perl

2019-03-18 13:29发布

Unlike Java, Perl uses reference count for garbage collection. I have tried searching some previous questions which speak about C++ RAII and smart pointers and Java GC but have not understood how Perl deals with the circular referencing problem.

Can anyone explain how Perl's garbage collector deals with circular references? Is there any way to reclaim circular referenced memory which are no longer used by the program or does Perl just ignores this problem altogether?

4条回答
可以哭但决不认输i
2楼-- · 2019-03-18 13:44

Have a look at Proxy Objects.

查看更多
Rolldiameter
3楼-- · 2019-03-18 13:51

According to my copy of Programming Perl 3rd ed., on exit Perl 5 does an "expensive mark and sweep" to reclaim circular references. You'll want to avoid circular references as much as possible because otherwise they won't be reclaimed until the program exits.

Perl 5 does offer weak references through the Scalar::Utils module.

Perl 6 will move to a pluggable garbage collected scheme (well, the underlying VM will have multiple garbage collection options and the behavior of those options can have an effect on Perl). That is, you'll be able to choose between various garbage collectors, or implement your own. Want a copying collector? Sure. Want a coloring collector? You got it. Mark/sweep, compacting, etc? Why not?

查看更多
倾城 Initia
4楼-- · 2019-03-18 14:00

The quick answer is that Perl 5 does not handle circular references automatically. Unless you take explicit measures in your code, any of your data structures which include circular references will not be reclaimed until the thread that created them dies. This is considered to be an acceptable tradeoff in that it avoids the need for runtime garbage collection that would slow down execution.

If your code creates data structures with circular references (i.e. a tree whose nodes contain references back to the root), you will want to use the Scalar::Util module to "weaken" the references that point back toward the root node. These weak references will not add to the reference count of whatever they point to, so the entire data structure will be automatically deallocated when the last external reference vanishes.

Example:

use Scalar::Util qw(weaken);

...

    my $new_node = { content => $content, root => $root_node };
    weaken $new_node->{root};
    push @{$root_node->{children}}, $new_node;

If you use code like this whenever you add new nodes to your data structure, then the only references to the root that are actually counted are those from outside of the structure. This is exactly what you want. Then the root, and recursively all of its children, will be reclaimed as soon as the last external reference to it vanishes.

查看更多
Juvenile、少年°
5楼-- · 2019-03-18 14:01

Perl applies a mark-and-sweep alternate GC in some occasions (when a thread dies, I think) in order to reclaim circular references. Note that the "every value is a string" Perl stanza makes it difficult to create true circular references; this is feasible, but "normal" Perl code does not, which is why reference counting works well with Perl.

查看更多
登录 后发表回答