in reply to Re^2: Memory leak
in thread Memory leak

I downloaded and ran your program and it produced a bunch of warnings. Most of them are probably benign, at leats with respect to your memory problem, but one group caught my eye and tweaked somthing in my memory:

Variable "@perl_widgets" will not stay shared at P:\test\422088.pl lin +e 3475. Variable "@checks_antiflats" will not stay shared at P:\test\422088.pl + line 4999. Variable "@antiflats_cmd" will not stay shared at P:\test\422088.pl li +ne 5005. Variable "@antiflats_nb" will not stay shared at P:\test\422088.pl lin +e 5035. Variable "@antiflats_ms" will not stay shared at P:\test\422088.pl lin +e 5056. Variable "@checks_antiflats" will not stay shared at P:\test\422088.pl + line 5076. Variable "$frame_ps_options" will not stay shared at P:\test\422088.pl + line 5087. Variable "$frame_ps_options" will not stay shared at P:\test\422088.pl + line 5104. Variable "$frame_ps_options" will not stay shared at P:\test\422088.pl + line 5122. Variable "$frame_ps_options" will not stay shared at P:\test\422088.pl + line 5138. Variable "$pythag_flag_last_time" will not stay shared at P:\test\4220 +88.pl line 5163. Variable "$frame_ps_options" will not stay shared at P:\test\422088.pl + line 5169. Variable "$pythag_flag_last_time" will not stay shared at P:\test\4220 +88.pl line 5192. Variable "$frame_ps_options" will not stay shared at P:\test\422088.pl + line 5218. Variable "$frame_ps_options" will not stay shared at P:\test\422088.pl + line 5318. Variable "@antiflats_nb" will not stay shared at P:\test\422088.pl lin +e 5324. Variable "@antiflats_ms" will not stay shared at P:\test\422088.pl lin +e 5325. Variable "$frame_ps_options" will not stay shared at P:\test\422088.pl + line 5349. Variable "@antiflats_nb" will not stay shared at P:\test\422088.pl lin +e 5366. Variable "@antiflats_ms" will not stay shared at P:\test\422088.pl lin +e 5370. Variable "$frame_ps_options" will not stay shared at P:\test\422088.pl + line 5422. Variable "@antiflats_nb" will not stay shared at P:\test\422088.pl lin +e 5428. Variable "@antiflats_ms" will not stay shared at P:\test\422088.pl lin +e 5429.

The diagnostics for this warning reads:

Variable "@perl_widgets" will not stay shared at P:\test\422088.pl lin +e 3475 (#4) (W closure) An inner (nested) named subroutine is referencing a lexical variable defined in an outer subroutine. When the inner subroutine is called, it will probably see the valu +e of the outer subroutine's variable as it was before and during the *f +irst* call to the outer subroutine; in this case, after the first call t +o the outer subroutine is complete, the inner and outer subroutines will + no longer share a common value for the variable. In other words, the variable will no longer be shared. Furthermore, if the outer subroutine is anonymous and references a lexical variable outside itself, then the outer and inner subrouti +nes will never share the given variable. This problem can usually be solved by making the inner subroutine anonymous, using the sub {} syntax. When inner anonymous subs tha +t reference variables in outer subroutines are called or referenced, + they are automatically rebound to the current values of such variables.

I wonder, without being able to find anything to confirm it, if these unshared closures are causing (part of) your memory leak.

As I say, I'm not sure if this could cause such a problem as I have never really understood the diagnostic, but it might be worth your further investigation.


Examine what is said, not who speaks.
Silence betokens consent.
Love the truth but pardon error.

Replies are listed 'Best First'.
Re^4: Memory leak
by demerphq (Chancellor) on Jan 14, 2005 at 09:55 UTC

    Maybe the following will help (and yes im pretty sure this is at least part of the reason for his leak):

    #!perl -l sub F { my $foo=bless[]; print "create:$foo"; sub T { print "T"; push @$foo,"test"; } print "F"; push @$foo,"bar"; } sub DESTROY { print "destroy: @_:@{$_[0]}" } F; T; T; T; F; __END__ create:main=ARRAY(0x15d53d8) F T T T create:main=ARRAY(0x1a4550c) F destroy: main=ARRAY(0x1a4550c):bar destroy: main=ARRAY(0x15d53d8):bar test test test

    T only once shares the same $foo with F, right at the beginning. The first time the sub executes it binds T as a closure to the original $foo and never rebinds it. And since T contains a reference to that $foo, and because T exists in the package table $foo wont be freed until T is destroyed causing $foo's refcount to drop. Thus the OP probably has a number of vars that are filling up without his knowledge behind the scenes. When the inner sub is anonymous, the compiler knows that the closure must be re-resolved each time.

    ---
    demerphq

      Thanks demerphq. I vaguely remembered reading an explanation of this a long time ago, but not where, nor any of the details. That explains it nicely.

      When I saw the "won't stay shared" warnings, saw that several of them related to arrays, and then looked inside and saw that several of the subroutines in question are being used within or from Tk UI callbacks, which tend to gets cycles many times, the alarm bells rang.

      It wasn't possible to actual do anything useful with the program to verify the notion, as it requires soecial format files.


      Examine what is said, not who speaks.
      Silence betokens consent.
      Love the truth but pardon error.
Re^4: Memory leak
by aplonis (Pilgrim) on Jan 15, 2005 at 02:49 UTC

    Yes, indeed. Those were problems, fixed now. For some reason I'd commented out the "use warnings" for some temporary reason and forgotten to turn it back on.

    I think the majority of my memory leak originated from that as fixing them all had good effect prior to any serious attempt with TK's "withdraw" and "raise" methods.

    My memory use now climbs up rapidly until the largest file has passed through the editor in auto-edit mode. Then it climbs only ever so very slowly with fifty or more windows being destroyed/re-created as per the other suggestion.

    Thanks much,
    Gan