sparky8342 has asked for the wisdom of the Perl Monks concerning the following question:

This code simulates a section of software that I'm writing:
(Devel::Leak is just to show what's happening).

-------------
#!/usr/bin/perl
use strict;

use Devel::Leak;

my $count;
my $count2;
my $diff;
my $handle;

$count = Devel::Leak::NoteSV($handle);

my %Hash = (1 => 'a', 2 => 'b');

my $Data = {};
$Data->{'one'}->{'two'} = \%Hash;

my $Data2;

push (@{$Data2->{'one'}->{'two'}},@{$Data->{'one'}->{'two'}});

undef ($Data);
undef ($Data2);

$count2 = Devel::Leak::CheckSV($handle);
$diff = $count2 - $count;

print "Difference: $diff\n";
---------------
There is a memory leak equivalent to the size of the hash being used.
Can anyone throw any light on this?
Thanks.

Replies are listed 'Best First'.
Re: Memory Leak
by merlyn (Sage) on Sep 26, 2001 at 17:19 UTC
    Well, this will leak:
    sub leaky { my %hash; $hash{'fred'} = 'flintstone'; $hash{'me'} = \%hash; } leaky(sleep 1) while 1;
    It leaks because it has a mutually-referencing data structure. Reference-counting cleanup can't fix this, any more than it can do it in C++. {grin} You need a mark/sweep garbage collection to catch this, and some version of that is proposed for Perl 6, but probably won't ever be retrofitted into Perl 5.

    The solution for now is "don't do that". Use weak references if you've got them. Otherwise, be sure you break the cycle somewhere before you exit the scope.

    -- Randal L. Schwartz, Perl hacker

Re: Memory Leak
by Zaxo (Archbishop) on Sep 26, 2001 at 18:11 UTC

    To add to merlyn's diagnosis, there's a canonical way of dealing with this in perl. Declare a package, bless the culprit into it, and define a sub DESTROY {...} which breaks the circular references by hand.

     "It's brutal, but it works."

    After Compline,
    Zaxo

Re: Memory Leak
by clintp (Curate) on Sep 26, 2001 at 17:07 UTC
    Did I miss something?
    $Data->{'one'}->{'two'}=\%Hash; # ... push (@{$Data2->{'one'}->{'two'}}, @{$Data->{'one'}->{'two'}}); # This's not an arrayref!
    This isn't completely valid code to begin with...
Re: Memory Leak
by sparky8342 (Acolyte) on Sep 26, 2001 at 17:03 UTC
    DOH!
    Sorry, this isn't right.
    The leak is caused by the %Hash still being in scope.
    There is a real problem in my code though, I will try and properly simulate it and post that.

Re: Memory Leak
by busunsl (Vicar) on Sep 26, 2001 at 17:17 UTC
    Just a hint:

    enclose your code in <code>/</code>-tags

    it will be more readable and better to cut out of the node.

    In your node the [\%Hash] is seen as \%Hash, which lead clintp down the wrong way.

Re: Memory Leak
by sparky8342 (Acolyte) on Sep 27, 2001 at 17:00 UTC
    Thanks for the code printing tip, I'll use that in future. It turns out that I was a bit hasty in my leak detection - It's actually something else which I'll post in a new node.