Re: Wx::Perl seems to be leaking memory

Steve Cookson <[email protected]> Thu, 21 May 2015 11:18:07 -0300
Newsgroups gmane.comp.lang.perl.wxperl
Message-ID <[email protected]>
Mark,

On 21/05/15 10:50, Mark Dootson wrote:
> Every Wx::Timer event or call to an overridden 'Notify' method leaks 1 
> SV. I don't have a solution but will work on it over the weekend. 
Amazing, I just came to the same conclusion, but I have no idea what to 
do from here.

I'll have a look too, but in the meantime, here is my sample code that 
demonstrates it. I don't used the over-ridden 'Notify' method.

Thanks very much,

Regards

Steve

#! /usr/bin/perl

package main;
use strict;
use warnings;

$main::app = App->new();
$main::app->MainLoop;

package App;
use strict;
use warnings;
use base 'Wx::App';

sub OnInit {

     my $frame = Launch->new();
     $frame->Show();

}

package Launch;
use strict;
use warnings;
use Wx qw(:everything);
use base qw(Wx::Frame);
use Devel::Leak;
sub new {
     my ($class, $parent) = @_;
     # Keep variable out of timer scope.
     our $handle;
     our $i;
     our $count_start;
     our $count_stop;

     my $i_frame = $class->SUPER::new($parent, -1, "Test wxTimer", 
wxDefaultPosition, wxDefaultSize);
     $i_frame->{panel} = Wx::Panel->new($i_frame, -1, wxDefaultPosition, 
wxDefaultSize);
     $i_frame->{sizer} = Wx::BoxSizer->new(wxVERTICAL);
     # Start and stop buttons.
     $i_frame->{button_start} = Wx::Button->new($i_frame->{panel}, -1, 
"Start", wxDefaultPosition, wxDefaultSize);
     $i_frame->{sizer}->Add($i_frame->{button_start});
     Wx::Event::EVT_BUTTON( $i_frame, $i_frame->{button_start}, sub {
     my ($self1, $event1) = @_;
     $i=0;
     $count_start=Devel::Leak::NoteSV($Launch::handle);
     print "Handle start: ", $count_start,"\n";
     $self1->{timer} -> Start();
     });
     $i_frame->{button_stop} = Wx::Button->new($i_frame->{panel}, -1, 
"Stop", wxDefaultPosition, wxDefaultSize);
     $i_frame->{sizer}->Add($i_frame->{button_stop});
     Wx::Event::EVT_BUTTON( $i_frame, $i_frame->{button_stop}, sub {
     my ($self1, $event1) = @_;
     $self1->{timer} -> Stop();
     $count_stop=Devel::Leak::CheckSV($Launch::handle);
     print "Handle stop: ", $count_stop,"\n";
     print "Count difference: ", $count_stop-$count_start,"\n";
     print "Loops: ", $i,"\n";

     });
     $i_frame->{panel}->SetSizer($i_frame->{sizer});
     $i_frame->{panel}->Layout();

     # Just do this 100 times to make sure there is no contribution to 
$handle count from Devel::Leak
     for (1..100){
     print "Handle init: ", Devel::Leak::NoteSV($Launch::handle),"\n";
     }
     $i_frame->{timer} = Wx::Timer->new( $i_frame, -1  );
     $i_frame->{timer} -> Start( 100, wxTIMER_CONTINUOUS ); # 600000
     Wx::Event::EVT_TIMER( $i_frame, $i_frame->{timer}, \&timer );

     return $i_frame;
}

# Don't do anything.
sub timer {
     ++$Launch::i;  # You can comment this out.  It makes no difference.
     return;
}