in reply to Re: Re: Re: Memory leak when using hash 'references'
in thread Memory leak when using hash 'references'

Thank you Foxcub, I will revisit all my code to see if there are any dangling references (seems like I could no longer rely on 'my' to free up memory for me, in case of references) and undef them.
-sureshr
  • Comment on Re: Re: Re: Re: Memory leak when using hash 'references'

Replies are listed 'Best First'.
Re: Memory leak when using hash 'references'
by jonadab (Parson) on Mar 14, 2003 at 02:35 UTC

    Additionally, be aware that Perl does not do lisp-style garbage collection; it just counts references. Consequently, if your data structure has any circular references (such as child objects that keep a reference back to their parents), letting them pass out of scope and clearing your variables that point to the whole structure won't do the trick. You have to walk the structure and undo the links from both ends. For example...

    { # WRONG: my @queue = (); foreach (@_) { my ($a, $b, $ch) = /(\d*)[:]([^:])[:](.*?)$/; my %parent = (a => $a, b => $b); my @children = map { my ($d, $e, $f) = split /:/, $_; my %c = (d=>$d, e=>$e, f=>$f, p=>\%parent); \%c; } split /,/, $ch; $parent{children}=\@children; push @queue, \%parent; } while (pop @queue) { do_stuff($_); } # The item that was popped off the queue now is out of scope, # but its children point back to it, so it stays in memory. } # Now the whole queue is out of scope, but the items formerly # in it are still in memory, even now -- and there's no way # to get back to them and free them, because you've lost # track of all the references, even though they still exist. { # BETTER: my @queue = (); foreach (@_) { my ($a, $b, $ch) = /(\d*)[:]([^:])[:](.*?)$/; my %parent = (a => $a, b => $b); my @children = map { my ($d, $e, $f) = split /:/, $_; my %c = (d=>$d, e=>$e, f=>$f, p=>\%parent); \%c; } split /,/, $ch; $parent{children}=\@children; push @queue, \%parent; } while (pop @queue) { do_stuff($_); foreach (@{$$_{children}}) { $$_{p}=undef; # child no longer has reference to parent. } undef $_; # Now there are zero references to the item, # so it does go away, taking with it its # ch key and the anon array that is its # value, which drops the refcount to each # element of that array to zero, causing # them to be freed, which in turn frees # each of the children -- I think. } }

    This is only your problem if you have any structures that point to eachother possibly forming a cycle of references. (The simplest case is pairs of mutually- referenced objects as above, but cases where a holds a ref to b that holds a ref to c that holds a ref to d that holds a ref to a will do the same thing.)


    for(unpack("C*",'GGGG?GGGG?O__\?WccW?{GCw?Wcc{?Wcc~?Wcc{?~cc' .'W?')){$j=$_-63;++$a;for$p(0..7){$h[$p][$a]=$j%2;$j/=2}}for$ p(0..7){for$a(1..45){$_=($h[$p-1][$a])?'#':' ';print}print$/}