Common Perl memory/reference leak patterns?

后端 未结 4 700
天命终不由人
天命终不由人 2020-12-04 18:15

I\'m chasing a couple of potential memory leaks in a Perl code base and I\'d like to know about common pitfalls with regards to memory (mis-)management in Perl.

What

4条回答
  •  时光说笑
    2020-12-04 19:00

    If the problem is in the Perl code, you might have a reference that points to itself, or a parent node.

    Usually it comes in the form of an object, that reference a parent object.

    { package parent;
      sub new{ bless { 'name' => $_[1] }, $_[0] }
      sub add_child{
        my($self,$child_name) = @_;
        my $child = child->new($child_name,$self);
        $self->{$child_name} = $child;   # saves a reference to the child
        return $child;
      }
    }
    { package child;
      sub new{
        my($class,$name,$parent) = @_;
        my $self = bless {
          'name' => $name,
          'parent' => $parent # saves a reference to the parent
        }, $class;
        return $self;
      }
    }
    {
      my $parent = parent->new('Dad');
      my $child  = parent->add_child('Son');
    
      # At this point both of these are true
      # $parent->{Son}{parent} == $parent
      # $child->{parent}{Son}  == $child
    
      # Both of the objects **would** be destroyed upon leaving
      # the current scope, except that the object is self-referential
    }
    
    # Both objects still exist here, but there is no way to access either of them.
    

    The best way to fix this is to use Scalar::Util::weaken.

    use Scalar::Util qw'weaken';
    { package child;
      sub new{
        my($class,$name,$parent) = @_;
        my $self = bless {
          'name' => $name,
          'parent' => $parent
        }, $class;
    
        weaken ${$self->{parent}};
    
        return $self;
      }
    }
    

    I would recommend dropping the reference to the parent object, from the child, if at all possible.

提交回复
热议问题