Wx::Perl seems to be leaking memory

Steve Cookson <[email protected]> Mon, 11 May 2015 10:32:15 -0300
Newsgroups gmane.comp.lang.perl.wxperl
Message-ID <[email protected]>
Hi Guys,

I started to talk about this on Perl Monks, you may have seen it here:

http://www.perlmonks.org/?node_id=1125580

An anonymous monk posted some code that showed just about every call to 
Wx leaking a scalar or two.  I've played about with the posted code and 
there is a copy attached to this email.

The main part of the code, here:

         $count1 =  Devel::Leak::NoteSV($handle);
         for(1..100){
             my $f=Wx::Frame->new( undef ,-1,"goner" );
             my $p=Wx::Panel->new (undef ,-1 );
             #my $b=Wx::Button->new ( $f ,-1 );
             #my $t=Wx::TextCtrl->new($f, -1, "");
             #$t->Destroy;
             #$b->Destroy;
             #$i->Destroy;
             $p->Destroy;
             $f->Destroy;
         }

         $count2 =  Devel::Leak::CheckSV($handle);

seems to show that if you do not ->Destroy a Wx object, it will not go 
out of scope naturally and even if you do destroy a Wx::Frame object, it 
will not go out of scope.  The monk also tried Weaken and undef, with 
the same results.

Please have a look at this and make sure that I have not (or the 
Anonymous Monk has not), made some fundamental error.

I have checked it both in 2.8.11 and 3.0.2 with the same results.

I look forward to hearing your feedback,

Regards

Steve.
perl_Leak_Mem_v2.pl (application/x-perl, 2.7 KB)
#!/usr/bin/perl --
use strict;
use warnings;

use Wx qw[:everything];
use Devel::Leak;
use Memory::Usage;
use Scalar::Util;

Main( @ARGV );
exit( 0 );
sub Main {
    Wx::InitAllImageHandlers();
    my $app = Wx::SimpleApp->new;
    my $frame = Wx::Frame->new( undef, -1, "", );
    $frame->SetBackgroundColour( Wx::wxBLACK() );
    $frame->SetSizer( Wx::BoxSizer->new( Wx::wxVERTICAL() ) );
    my $text = Wx::TextCtrl->new(
        $frame, -1,
        join( ' ', "\n", Perl => $], Wx => $Wx::VERSION, Wx::wxVERSION_STRING, "\n" ),
        [ -1, -1 ],
        [ -1, -1 ],
        Wx::wxTE_MULTILINE()
    );
    my $b1 = Wx::Button->new( $frame , -1, "Test", );
    Wx::Event::EVT_BUTTON( $frame, $b1, sub {
        my $count1=0;
        my $count2=0;
        my $handle="";
        $count1 =  Devel::Leak::NoteSV($handle);
        for(1..100){
            my $f=Wx::Frame->new( undef ,-1,"goner" );
            my $p=Wx::Panel->new (undef ,-1 );
            #my $b=Wx::Button->new ( $f ,-1 );
            #my $t=Wx::TextCtrl->new($f, -1, "");
            #$t->Destroy;
            #$b->Destroy;
            #$i->Destroy;
            $p->Destroy;
            $f->Destroy;
        }
        
        $count2 =  Devel::Leak::CheckSV($handle);
        
        $text->AppendText( join '', "Count1 = '",$count1,"'\n", "Count2 = '",$count2,"'\n", "Diff = '",$count2-$count1,"'\n" );
        $text->AppendText( psmem('new f new p') );
    } );
    $frame->GetSizer->Add( $text,  1, Wx::wxEXPAND() );
    $frame->GetSizer->Add( $b1, 0,0 ) ;
    $frame->Show(1);
    $app->SetTopWindow( $frame );
    $text->AppendText( psmem('MainLoop') );
    $app->MainLoop;
}

sub psmem {
    my ( $msg ) = @_;
    my @lines = qx{pslist -m $$       2>NUL}; ## http://live.sysinternals.com/pslist.exe
    shift @lines for 1..3;
    chomp @lines;
#~     print join "\n", @lines, "";
#~ Name                Pid      VM      WS    Priv Priv Pk   Faults   NonP Page
#~ perl               1052   25348    7220    4504    4512     1977      2   33
    my %ps;
@ps{'Name',
'Pid',
'VM',
'WS',
'Priv',
'Priv Pk',
'Faults',
'NonP',
'Page' } = grep length, split /\s+/, shift @lines;
#~    Pri         Priority
#~    Thd         Number of Threads
#~    Hnd         Number of Handles
#~    VM          Virtual Memory
#~    WS          Working Set   ------ "Mem Usage" in taskmanager
#~    Priv        Private Virtual Memory   ------ "VM Size" in taskmanager
#~    Priv Pk     Private Virtual Memory Peak
#~    Faults      Page Faults
#~    NonP        Non-Paged Pool
#~    Page        Paged Pool
#~    Cswtch      Context Switches
#~     use DDS; Dump(\@lines , \%ps);
#~     print "VM: $ps{VM}   RSS: $ps{WS}   - $msg\n";    
    return "VM: $ps{VM} < WS: $ps{WS} VM: $ps{Priv} >      $msg\n";    

}


__END__