crabbdean has asked for the wisdom of the Perl Monks concerning the following question:
I have a class that includes an iterator method for outputing in a stream-like fashion. (tye's response in this thread shows pretty much how the code is constructed Re: Streaming to Handles (iterator)) Since this I've slightly amended the code to include some other "features". It all works beautifully although I've noticed it now leaks memory. I believe I've located the source of the memory leak although am not sure how to retain the features while effectively removing the memory leak. The below code highlights the problem.
I push an array reference to the $self->{files} array by using the below code:
In the "next" iterator method I then "return" these references from the $self->{files} array:
Is there a way to achieve this without leaving a reference count against @array (and hence removing the memory leak) ?
Does all of that make sense?
UPDATE: After writing this I layed down in bed and a thought suddenly struck me - Instead of making an @array to reference why not just push an anonymous array?
Dean
The Funkster of Mirth
Programming these days takes more than a lone avenger with a compiler. - sam
RFC1149: A Standard for the Transmission of IP Datagrams on Avian Carriers
I push an array reference to the $self->{files} array by using the below code:
(I'm sure that's where the problem lies!)my @array = (); push (@array, $rel_path); ## in my code more than one thing is pushed to @array. push (@{$self->{files}}, \@array);
In the "next" iterator method I then "return" these references from the $self->{files} array:
... which I then dereference in my calling script:sub next { my( $self )= @_; while( 1 ) { if( @{ $self->{files} } ) { my $file = shift @{ $self->{files} }; ## HERE! if( -d $file ) { push @{ $self->{dirs} }, $file; } return $file; } if( ! @{ $self->{dirs} } ) { return; } my $dir= shift @{ $self->{dirs} }; if( opendir( DIR, $dir ) ) { $self->{files}= [ map { File::Spec->catfile( $dir, $_ ); } File::Spec->no_upwards( readdir(DIR) ) ]; closedir DIR; } else { warn "opendir failed, $dir: $!\n"; } } }
Now I can see this method of pushing array references is leaving a reference count against the @array array ... and hence @array is never destroyed. This in time means RAM gets munched and for a long running script eventuates in my computer dying. But I need the feature of pushing a set of values (possbily as a array unless there is an alternative) into the $self->{files} array which I can then recall together as setmy $file; while( $file = $f->next() ) { print "@{$_}\n"; }
Is there a way to achieve this without leaving a reference count against @array (and hence removing the memory leak) ?
Does all of that make sense?
UPDATE: After writing this I layed down in bed and a thought suddenly struck me - Instead of making an @array to reference why not just push an anonymous array?
I'll have to test this tomorrow but if anyone wishes to comment then please do so. :-)push (@{$self->{output}}, [$rel_path, $var1, $var2]);
Dean
The Funkster of Mirth
Programming these days takes more than a lone avenger with a compiler. - sam
RFC1149: A Standard for the Transmission of IP Datagrams on Avian Carriers
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Memory Management and Array references
by dave_the_m (Monsignor) on May 25, 2004 at 12:56 UTC | |
by crabbdean (Pilgrim) on May 25, 2004 at 13:14 UTC | |
Re: Memory Management and Array references
by chromatic (Archbishop) on May 25, 2004 at 17:15 UTC | |
by crabbdean (Pilgrim) on May 25, 2004 at 21:05 UTC | |
by hv (Prior) on May 25, 2004 at 21:58 UTC | |
Re: Memory Management and Array references
by crabbdean (Pilgrim) on Jul 19, 2004 at 22:02 UTC |
Back to
Seekers of Perl Wisdom