Dan Mercer wrote:
> Hi folks,
>
> I have some tools that make use of the perl bindings to Subversion
> 1.3. As we are dealing with moderate amounts of data in long running
> processes, we are managing memory using the SVN::Pool interface but it
> appears that we are leaking memory. The leak I am focusing on right
> now is related to how I am calling SVN::Fs::file_contents, (though I
> have found other leaks in at least my usage of apply_textdelta and
> send_string).
The leak I described appears be in the getline method of SVN:Stream (in
Core.pm):
sub getline
{
my $self = shift;
*$self->{pool} ||= SVN::Core::pool_create (undef);
my ($buf, $eof) = *$self->{svn_stream}->readline ($/, *$self->{pool});
return undef if $eof && !length($buf);
return $eof ? $buf : $buf.$/;
}
It appears that SVN::Stream, $self->{pool} will never exist and so is
always allocated for the read. This memory is not cleaned up, even if a
default pool is created prior to the read. Fortunately, file contents
can be read using the 'read' method in a way that doesn't cause a memory
leak:
my $stream = SVN::Fs::file_contents($root, $path, $pool);
my $size = SVN::Fs::file_length($root, $path, $pool);
my $data =
''; #
must be a scalar and not undef!
$stream->read($data, $size); #
$data contains file contents
I am including a patch to my earlier script that demonstrates that
<$stream> still leaks, even if a subpool has been explicitly created. It
also demonstrates a non-leaky read of file contents using the read method.
--- svn_find_leak.pl Thu Apr 13 10:50:24 2006
+++ svn_find_leak2.pl Thu Apr 13 12:43:34 2006
@@ -30,13 +30,20 @@
# the test looks like our actual use-case, but if you do away with
# this and just allocate from $p, the leak will still occur.
my $sp = SVN::Pool->new($p);
- my $stream = SVN::Fs::file_contents($root, $path, $sp);
# we only leak if we try to read from $stream
if (defined $leak) {
+ $sp->default();
+ my $stream = SVN::Fs::file_contents($root, $path, $sp);
my $contents = <$stream>;
+ $stream = undef;
+ } else {
+ my $contents = '';
+ my $stream = SVN::Fs::file_contents($root, $path, $sp);
+ my $size = SVN::Fs::file_length($root, $path, $sp);
+ $stream->read($contents, $size);
+ $stream = undef;
}
# cleanup
- $stream = undef;
$sp = undef;
Hopefully this will be helpful to those making use of the perl bindings
to SVN. I would submit a patch for getlines(), but I'm not really sure
what the appropriate fix should be... maybe this will help someone with
greater perl skills than myself devise a real fix.
Dan M.
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org
Received on Thu Apr 13 22:13:48 2006