Message Boards Message Boards

0
|
12444 Views
|
5 Replies
|
2 Total Likes
View groups...
Share
Share this post:

Module trash collection behaviour

Posted 11 years ago
The mathematica Module function is supposed to create temporary variables which are supposed to be deleted after the Function completes. However sometimes it doesn't.

For example consider the following mathematica code:
Module[{x}, x /. NDSolve[x'[t] == 1 && x[0] == 0, x, {t, 0, 1}][[1]]]

After evaluation the Global context will contain the temporary variable x$(ModuleNumber)
In[2]:= Names["@$@"]
Out[2]= {"x$759"}

Is this behaviour just a bug or is it a hidden feature? If so, do people know under exactly what conditions Mathematica does not get rid off temporary Module variable?

Maybe more importantly, do people know a good work around for it? (In length computations involving lots of modules the accumulating leftover module variables will steadily eat up all system memory).
5 Replies
As an update here are some links reporting similar behaviour sometimes by design, sometimes clearly buggy:
http://stackoverflow.com/questions/6867892/reducing-memory-usage-in-an-extended-mathematica-session
http://groups.google.com/group/comp.soft-sys.math.mathematica/msg/f95a9588b9803f54
http://forums.wolfram.com/mathgroup/archive/2011/Aug/msg00012.html

Summarizing here are some typical examples where Mathematica does not clear Module generated temporary variables:

1.
Module[{x}, x /. NDSolve[x'[t] == 1 && x[0] == 0, x, {t, 0, 1}][[1]]]
Result: x$NNN is not removed.
Reason: ¿ NDSolve stores some expressions referencing x$NNN in the system cache ?
Solution: Clear system cache. (Presumably this will happen on its own as the kernel session progresses.)

2.
Module[{y, z, a, b}, a = y + z; b = 2*a];
Result: y$NNN and z$NNN are not removed from global context.
Reason: y$NNN and z$NNN appear in the module output and are thus referenced by Out.
Solution: Clear Out, or more systematically limit the History Length through $HistoryLength


3.
Module[{x}, f = x]
Result: x$NNN is not removed from global context.
Reason: Definition of f is referencing x$NNN
Solution: Clear f.

4.
a[b_] := Module[{x}, x := 1; x /; b]
a[True]
Result:a x$NNN is permanently placed in the global context every time a is called.
Reason: Unknown. This appears to be a bug.  (Clear and ClearSystemCache[] do not remove the x$NNN.)

5.
Module[{a, b},
a[i_] := b[i - 1];
b[i_] := a[i - 1];
a[0] = 0; b[0] = 0; a[10]]
Result: a$NNN and b$NNN remain in global context.
Reason: Unknown. Bug?


It would be very helpful if someone could explain the behaviour of 4. and 5. (and how to avoid it).
Hmm, good point (and one I should have noticed). The behaviour seems to be automated and odd, as in
Module[{y, z, a, b}, a = y + z; b = 2*a];
Names["@$@"]

Hopefully someone else can provide more information, as I'm interested as well.
POSTED BY: Martin Hadley
@ Martin:
 The example you give acts as one would expect. Evaluation of that module leaves y$NNN and z$NNN in the global context because those are present in the output of the module (2 (y$NNN + z$NNN)).

If you set $HistoryLength=0. Mathematica will actually remove those temporary symbols, as they are no longer used.

Update:
In the example I gave, the persistent temporary variables are in fact removed if you clear the SystemCache. So it appears, that in that case NDSolve is storing some expressions involving that variable in the system cache.
But I have also encountered much more complicated examples clearing the system cache does not help. (I'll try to cook up a simple example)

Update example:

Compare:
 In[80]:= Remove["@$@"]
 Module[{a, b},
  a[i_] := b[i - 1];
  b[i_] := a[i - 1];
  a[0] = 0; b[0] = 0; a[10]]
 ClearSystemCache[];
 Names["@$@"]
 
 Out[81]= 0
Out[83]= {"a$7421", "b$7421"}[/i][/i]

With:
 In[84]:= Remove["@$@"]
 Module[{a, b},
  a[i_] := b[i - 1];
  b[i_] := b[i - 1];
  a[0] = 0; b[0] = 0; a[10]]
 ClearSystemCache[];
 Names["@$@"]
 
 Out[85]= 0
Out[87]= {}[/i][/i]
Module is not meant to forget about its variables, they always get added to the Global context - http://reference.wolfram.com/mathematica/tutorial/HowModulesWork.html

You may find Block or With more useful for this kind of purpose, there's a tutorial to the difference between Block and Module here http://reference.wolfram.com/mathematica/tutorial/BlocksComparedWithModules.html. You'll find With useful where you need to evade Hold* attributes.
POSTED BY: Martin Hadley
@martin:

The variable generated by Module are supposed to be temporary, i.e. they should be deleted as soon as they are no longer needed.

See the article you quoted:
Symbols generated by Module behave in exactly the same way as other symbols for the purposes of evaluation. However, these symbols carry the attribute Temporary, which specifies that they should be removed completely from the system when they are no longer used. Thus most symbols that are generated inside modules are removed when the execution of those modules is finished. The symbols survive only if they are explicitly returned.
(Note that the last sentence is apparently not true, since in the example provided the variable is not explicitly returned.)

Also note that Block and With are not suitable for what I need. (Local variables inside functions, which do not interact with existing global definitions)
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract