Re: Embedded widgets in HList and Text leaking memory?

Slaven Rezic <[email protected]> 04 Mar 2007 12:22:50 +0100
Newsgroups gmane.comp.lang.perl.tk
Message-ID <[email protected]>
Michael Erskine <[email protected]> writes:

> On Thursday 22 February 2007 09:36, [email protected] wrote:
> > How do you remove the embedded widgets? I guess that you need both,
> > removing the widget
> > from the container widget *and* explicitely destroying the embedded widget
> > using destroy().
> 
> Hi Slaven,
> At the moment I'm using the delete method of the Text widget (with 
> delete('1.0', 'end')) which claims in the manpage to destroy embedded 
> windows. I did consider explicitly destroying the embedded widgets but I 
> haven't yet tackled programmatically finding them in the Text widget!
> 
> Anyhow, here follows a version of the sort of thing I'm trying to achieve that 
> I've made standalone. I really love the flexibility of using a Text widget 
> but I still need to learn a lot more about it! On Windows the leakage seems 
> much worse than on Linux but that could be a Tk version thing.
> 

I see the memory leak also on FreeBSD. And it also seems that deleted
embedded windows are really destroyed. But with a script that just
adds and deletes embedded widget into a Text widget (see below)
there's no such leakage (well, there's a minimal leak of 16 bytes per
iteration). It must be something else in your script, maybe one of the
options causing the leakage.

Generally it's a good idea to reuse widgets in Tk to avoid all kind of
memory problems.

Regards,
        Slaven

#!/usr/bin/perl -w

use strict;
use Tk;
use Devel::Leak;

my $top = new MainWindow;
$top->geometry("+0+0");
my $t = $top->Text->pack;
my $i = 0;
while(){
    my $handle;
    Devel::Leak::NoteSV($handle);
    $t->windowCreate("end", -window => $t->Spinbox());
    #$t->update;
    $t->delete("1.0","end");
    Devel::Leak::CheckSV($handle);
    warn $i++ . " " . join(",", currmem());
    #select undef,undef,undef,0.1;
}

MainLoop;

# REPO BEGIN
# REPO NAME currmem /home/e/eserte/work/srezic-repository 
# REPO MD5 0d92d919295edb67c31d5b1bbb652305

=item currmem([$pid])

=for category System

Return ($mem, $realmem) of the current process or process $pid, if $pid
is given.

On Linux, an even shorter alternative for getting the virtual memory is:

    cat /proc/self/stat | cut -d" " -f 23

=cut

sub currmem {
    my $pid = shift || $$;
    if (open(MAP, "dd if=/proc/$pid/map bs=64k 2>/dev/null |")) { # FreeBSD
	my $mem = 0;
	my $realmem = 0;
	while(<MAP>) {
	    my(@l) = split /\s+/;
	    my $delta = (hex($l[1])-hex($l[0]));
	    $mem += $delta;
	    if ($l[11] ne 'vnode') {
		$realmem += $delta;
	    }
	}
	close MAP;
	($mem, $realmem);
    } elsif (open(MAP, "/proc/$pid/maps")) { # Linux
	my $mem = 0;
	my $realmem = 0;
	while(<MAP>) {
	    my(@l) = split /\s+/;
	    my($start,$end) = split /-/, $l[0];
	    my $delta = (hex($end)-hex($start));
	    $mem += $delta;
	    if (!defined $l[5] || $l[5] eq '') {
		$realmem += $delta;
	    }
	}
	close MAP;
	($mem, $realmem);
    } else {
	undef;
    }
}
# REPO END

__END__


-- 
Slaven Rezic - slaven <at> rezic <dot> de

    Berlin Perl Mongers - http://berlin.pm.org
--++**==--++**==--++**==--++**==--++**==--++**==--++**==
ptk mailing list
[email protected]
https://mailman.stanford.edu/mailman/listinfo/ptk