sub r {return if !$_[0]; r($_[0]-1); } leaktrace{ r(1);};

jozef on 2010-06-22T17:22:15

Today @$work we discovered that even dummy recursive calling of a function is leaking memory. Here is the one-liner 10000x calling it self and returning:

perl -MEnglish -MGTop -le 'my $g=GTop->new();$m=$g->proc_mem($PID);print $m->size; sub r { return if not $_[0]; r($_[0]-1); } r(100000); $m=$g->proc_mem($PID); print $m->size;'

The output is:

7122944
34729984

Before the recursion 7MB allocated. After the recursion (that finished) 34MB...

Here is what Test::LeakTrace say about it:

$ perl -MTest::LeakTrace -le 'sub r { return if not $_[0]; r($_[0]-1); } leaktrace{ r(1); };'
leaked ARRAY(0x9b7e8e8) from -e line 1.
leaked SCALAR(0x9b98cb8) from -e line 1.
leaked ARRAY(0x9c311f8) from -e line 1.
leaked SCALAR(0x9c311e8) from -e line 1.

Are we doing anything wrong? Is it ok? How to release the memory?


Re: sub r {return if !$_[0]; r($_[0]-1); } leaktra

daxim on 2010-06-22T17:28:21

#p5p

[16:49] <shadowpaste> "daxim" at 217.168.150.38 pasted "recursion does not release memory for reuse?" (14 lines) at http://paste.scsys.co.uk/45082
[16:49] <dipsy> [ magnet_web paste from "daxim" at 217.168.150.38... ]
[16:49] <daxim> what's going on here?
[16:50] <Zefram> fragmentation?
[16:50] <purl> fragmentation is interesting
[16:50] <Nicholas> no, Pad frames created for recursion are not released
[16:50] <Nicholas> the assumption is that you'll recurse again
[16:51] <Nicholas> patches not unwelcome to add the option to change this
[16:51] <Nicholas> but I've not thought totally about how to do it
[16:51] <Nicholas> you could, in theory, do it from XS
[16:51] <Nicholas> manually, on subrouties by passing in a reference to them
[16:52] <Zefram> keeping pads beyond N levels deep seems like a bad idea
[16:53] <Nicholas> actually, better I think is is "keeping pads N levels deeper than the level you just left"
[16:53] <Zefram> if you're recursing deep, you're spending enough time that the overhead of reallocating pads is probably not a worry
[16:53] <Zefram> yes, was just about to suggest that.  hysteresis
[16:53] <Nicholas> that would avoid penalising things that recurse and stay recursed
[16:53] <Zefram> yes

Re: sub r {return if !$_[0]; r($_[0]-1); } leaktra

jozef on 2010-06-22T17:48:15

perl -MTest::LeakTrace -le 'sub r {return if !$_[0]; r($_[0]-1); } r(1); leaktrace{ r(1);};'

Hmm yes the second recursion calling is not leaking memory any more.