possible memleak?
John W. Eaton
jwe at octave.org
Tue Mar 3 13:37:29 CST 2009
On 2-Mar-2009, Søren Hauberg wrote:
| man, 02 03 2009 kl. 18:55 +0100, skrev Søren Hauberg:
| > I'm I missing something obvious here, or do we have a
| > memleak?
|
| Sorry about replying to my own mail so fast, but I just realised the
| following program (which is much more simple) also leaks:
|
| while (true), f = @(t) exp(t); end
|
| So, it seems creating/deleting function handles leaks memory.
This bug report pointed out several problems.
First, there was a stupid mistake with the assignment operator for the
symbol_table::symbol_record class. I don't know what I was thinking
when I wrote that, but it took a long time to find. Even though I was
looking right at the problem, I just didn't spot it for way too
long... There was a similar problem with the symbol_table::fcn_info
class which is also fixed by the patch below.
Another problem was that the symbol_table::do_inherit function was
copying all symbols from the parent scope, and that could cause what
appeared to be a memory leak. We were copying all symbols in an
attempt to make things like
function r = f2 (f, x)
r = f (x);
end
function f = f1 (k)
f = @(x) f2 (@(y) y-k, x);
end
f = f1 (3) ==> @(x) fcn2 (@(y) y - k, x)
f (10) ==> 7
work as expected, given that the nested anonymous function was set to
look in its parent (the enclosing anonymous function object) for any
undefined symbols. But this also had the affect of leading to a chain
of copied symbol tables in something like
for i = 1:n
f = @(x) sin (x);
endfor
which appears to leak memory until the last constructed function
handle is deleted. The reason for the apparent leak was that copying
function handles from the parent symbol table meant that the first
time through the loop everthing is OK (F is yet to be defined), but
the second time, we inherit the previous value of F, which contains
other symbols from the parent scope, then the third time, we inherit
the new value of F which contains the previous value of F, which
contains other symbols from the parent scope, etc.
Now when processing nested anonymous functions like this, Octave will
only look in the overall containing scope instead of just up into the
anonymous function that contains the nested anonymous function. This
is done by walking the parse tree of the body of the anonymous
function and transforming any tree_anon_fcn_handle (parse tree)
objects to tree_constant (parse tree) objects that contain
octave_fcn_handle objects with the symbol table of the "handled"
function filled in with values from the scope that contains the set of
nested anonymous functions.
Note that the tree walking was already implemented in the dup
functions, but it was not doing the transformation. It would probably
also be best to convert the dup functions to use the tree_walker
pattern, so I'll try to take a look at doing that at some point.
I checked in the following change:
http://hg.savannah.gnu.org/hgweb/octave/rev/ab87d08d9a1b
Thanks,
jwe
More information about the Bug-octave
mailing list