Skip Menu |

This queue is for tickets about the XML-Generator CPAN distribution.

Report information
The Basics
Id: 4513
Status: resolved
Priority: 0/
Queue: XML-Generator

People
Owner: Nobody in particular
Requestors: mrk21 [...] infradead.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 0.93
Fixed in: (no value)



Subject: Memory leak on XML::Generator-0.93 (included)
Module: XML::Geenrator-0.93 perl: v5.8.0 uname output: Linux, 2.4.20-4GB, i686, GNU/Linux Creating an XML::Generator object with XML::Generator->new generates a memory leak: The "new" method places a reference to a subroutine in the %tag_factory hash, the subroutine contains a reference to the corresponding object. Objects that are no longer used will never go out of scope. Supplied is a patch to the XML::Generator module (v 0.93) which fixes this plus a test script for the t/ directory, which is repeated below [ ps: please contact me if the server doesn't accept patch file and I'll email it ]. #!/usr/bin/perl -w use strict; use XML::Generator; # assumes presence of a /proc filesystem # and that the file /proc/<process id>/statm # contains the memory useage information print "1..1\n"; sub printmem { my $text = shift; local *FILE; open FILE, "</proc/$$/statm"; my $line = <FILE>; close FILE; chomp $line; my @figures = map { $_ * 4 } split /\s+/, $line; print "$text $figures[0]\n"; return $figures[0]; } print "# memory use with XML::Generator->new call inside loop\n"; my %a = map {$_,1} qw ( 1 10 100 1000 10000 ); my %mem = %a; foreach my $i ( 1 .. 10000 ) { my $x = new XML::Generator( 'escape' => 'always', 'conformance' => 'strict' ); my $s = $x->xml( $x->a( $x->b )); $a{$i} and $mem{$i} = &printmem( "# Program size after $i iterations : " ); } print $mem{1000} eq $mem{10000} ? "ok 1 # memory stays at around $mem{1000}kB\n" : "not ok 1 # memory grown from $mem{100}kB => $mem{10000}kB after 10,000 iterations\n"; # # TODO: make test more fuzzy? #
diff -N -r -u XML-Generator-0.93/Generator.pm XML-Generator-0.93-patched/Generator.pm --- XML-Generator-0.93/Generator.pm 2003-01-22 15:41:05.000000000 +0000 +++ XML-Generator-0.93-patched/Generator.pm 2003-11-28 02:40:42.000000000 +0000 @@ -271,6 +271,7 @@ my ($tag) = $AUTOLOAD =~ /.*::(.*)/; unshift @_, $tag; + unshift @_, $this; goto &{ $tag_factory{$this} }; } @@ -459,6 +460,7 @@ return XML::Generator::cdata->new([$xml]); } +=pod =head2 xml "Final" XML document. Must be called with one and exactly one @@ -657,21 +659,30 @@ # the tag. sub tag { - my $sub = XML::Generator::util::c_tag(shift); + my $sub = XML::Generator::util::c_tag($_[0]); goto &{ $sub } if $sub; } # Generate a closure that encapsulates all the behavior to generate a tag sub c_tag { - my $this = shift; + my $arg = shift; + + my $strict = $arg->{'conformance'} eq 'strict'; + $arg->{'always'} = (my $escape = $arg->{'escape'}) & XML::Generator::ESCAPE_ALWAYS; + $arg->{'high_bit'} = $escape & XML::Generator::ESCAPE_HIGH_BIT; + my $empty = $arg->{'empty'}; + my $pretty = $arg->{'pretty'}; + undef $arg; + return sub { + + my $this = shift; my $strict = $this->{'conformance'} eq 'strict'; - my $always = (my $escape = $this->{'escape'}) & XML::Generator::ESCAPE_ALWAYS; - my $high_bit = $escape & XML::Generator::ESCAPE_HIGH_BIT; + my $always = $this->{'always'}; + my $high_bit = $this->{'high_bit'} ; my $empty = $this->{'empty'}; my $pretty = $this->{'pretty'}; - return sub { my $tag = shift || return undef; # catch for bad usage # parse our argument list to check for hashref/arrayref properties diff -N -r -u XML-Generator-0.93/t/Generator_memoryleak.t XML-Generator-0.93-patched/t/Generator_memoryleak.t --- XML-Generator-0.93/t/Generator_memoryleak.t 1970-01-01 01:00:00.000000000 +0100 +++ XML-Generator-0.93-patched/t/Generator_memoryleak.t 2003-11-28 02:34:53.000000000 +0000 @@ -0,0 +1,53 @@ +#!/usr/bin/perl -w + +use strict; +use XML::Generator; + +# assumes presence of a /proc filesystem +# and that the file /proc/<process id>/statm +# contains the memory useage information + +sub exit_txt +{ + print "$_[0]\n"; + exit; +} + +print "1..1\n"; +-d "/proc" or &exit_txt( "ok 1 \# skip Filesystem /proc does not seem to exist on this OS" ); +-d "/proc/$$" or &exit_txt( "not ok 1 \# todo /proc filesystem seems to exist, but cannot /proc/<process id> directory in filesystem" ); +-f "/proc/$$/statm" or &exit_txt( "ok 1 \# skip /proc filesystem seems to exists but /proc/<process id>/statm memory status file does not seem to exist" ); + + +sub printmem +{ + my $text = shift; + local *FILE; + open FILE, "</proc/$$/statm"; + my $line = <FILE>; + close FILE; + chomp $line; + my @figures = map { $_ * 4 } split /\s+/, $line; + print "$text $figures[0]\n"; + return $figures[0]; +} + +print "# memory use with XML::Generator->new call inside loop\n"; + +my %a = map {$_,1} qw ( 1 10 100 1000 10000 ); +my %mem = %a; +foreach my $i ( 1 .. 10000 ) +{ + my $x = new XML::Generator( 'escape' => 'always', + 'conformance' => 'strict' ); + my $s = $x->xml( $x->a( $x->b )); + $a{$i} and $mem{$i} = &printmem( "# Program size after $i iterations : " ); +} + +print $mem{1000} eq $mem{10000} ? + "ok 1 # memory stays at around $mem{1000}kB\n" : + "not ok 1 # memory grown from $mem{100}kB => $mem{10000}kB after 10,000 iterations\n"; + +# +# TODO: make test more fuzzy? +#
From: "Benjamin Holzman" <bholzman [...] earthlink.net>
To: <bug-XML-Generator [...] rt.cpan.org>
Subject: Re: [cpan #4513] Memory leak on XML::Generator-0.93 (included)
Date: Mon, 1 Dec 2003 09:09:09 -0500
RT-Send-Cc:
Thanks for the bug report! Unfortunately, the patch file you sent never made it to me, so could you resend it? Thanks, Benjamin Holzman Show quoted text
----- Original Message ----- From: "Guest via RT" <bug-XML-Generator@rt.cpan.org> To: <AdminCc of cpan Ticket #4513 :> Sent: Thursday, November 27, 2003 10:03 PM Subject: [cpan #4513] Memory leak on XML::Generator-0.93 (included)
> > This message about XML-Generator was sent to you by guest <> via
rt.cpan.org
> > Full context and any attached attachments can be found at: > <URL: https://rt.cpan.org/Ticket/Display.html?id=4513 > > > > Module: XML::Geenrator-0.93 > perl: v5.8.0 > uname output: Linux, 2.4.20-4GB, i686, GNU/Linux > > Creating an XML::Generator object with XML::Generator->new generates a
memory leak: The "new" method places a reference to a subroutine in the %tag_factory hash, the subroutine contains a reference to the corresponding object. Objects that are no longer used will never go out of scope.
> > Supplied is a patch to the XML::Generator module (v 0.93) which fixes this
plus a test script for the t/ directory, which is repeated below [ ps: please contact me if the server doesn't accept patch file and I'll email it ].
> > #!/usr/bin/perl -w > > use strict; > use XML::Generator; > > # assumes presence of a /proc filesystem > # and that the file /proc/<process id>/statm > # contains the memory useage information > > print "1..1\n"; > > sub printmem > { > my $text = shift; > local *FILE; > open FILE, "</proc/$$/statm"; > my $line = <FILE>; > close FILE; > chomp $line; > my @figures = map { $_ * 4 } split /\s+/, $line; > print "$text $figures[0]\n"; > return $figures[0]; > } > > print "# memory use with XML::Generator->new call inside loop\n"; > > my %a = map {$_,1} qw ( 1 10 100 1000 10000 ); > my %mem = %a; > foreach my $i ( 1 .. 10000 ) > { > my $x = new XML::Generator( 'escape' => 'always', > 'conformance' => 'strict' ); > my $s = $x->xml( $x->a( $x->b )); > $a{$i} and $mem{$i} = &printmem( "# Program size after $i iterations :
" );
> } > > print $mem{1000} eq $mem{10000} ? > "ok 1 # memory stays at around $mem{1000}kB\n" : > "not ok 1 # memory grown from $mem{100}kB => $mem{10000}kB after
10,000 iterations\n";
> > # > # TODO: make test more fuzzy? > # >