15
$\begingroup$

For this code:

(* Cell 1 *)
generate := Module[{x}, x = Range[100 * 1000 * 1000]; x];

(* Cell 2 *)
g = generate[];
MemoryInUse[]

If I evaluate cell 2 repeatedly, the memory consumption keeps growing by 400 MB each time (as seen in the OS task manager). For some reason, it seems that Mathematica does not free the memory taken by the old value of g.

Can someone please explain what is going on here? And is there a way to force the freeing of old g values? Due to this issue I need to keep on quitting the Mathematica kernel.

$\endgroup$
2
  • $\begingroup$ Sometimes just calling Share[] already frees substantial memory. $\endgroup$
    – celtschk
    Mar 22, 2012 at 21:20
  • 1
    $\begingroup$ @celtschk Share[] works by making sure that the same expression is not stored twice. It uses pointers for duplicate occurrences, such as in x^2 in f[x^2, x^2]. Unfortunately it won't help with packed arrays like the one in the OP's example. $\endgroup$
    – Szabolcs
    Mar 22, 2012 at 21:27

2 Answers 2

17
$\begingroup$

You need to set

$HistoryLength = 0

(or other small value) at the beginning of the session to prevent Out from remembering previous outputs. One non-obvious thing about Out is that if we do

In[1]:= a=1;

then Out[1] will still be set to 1 despite the semicolon at the end of the input!

There's also the CleanSlate` package which has a ClearInOut function that clears old inputs and outputs.

$\endgroup$
5
  • 6
    $\begingroup$ If you define ignore[_]:=Null you can selectively avoid this storage by writing ignore[a=1] instead of a=1;. Note that (a=1;Null) seems not to be sufficient. $\endgroup$
    – celtschk
    Mar 22, 2012 at 21:26
  • $\begingroup$ @celtschk Yep, though seems like a lot of work. Interesting observation about adding Null. $\endgroup$
    – Szabolcs
    Mar 22, 2012 at 21:30
  • $\begingroup$ @celtschk I sometimes would do a=1 //Null& which is the same as you do. Probably the Null doesn't work because the actual full form of a; is CompoundExpression[a, Null], equivalent to appending Null $\endgroup$
    – Rojo
    Mar 23, 2012 at 1:52
  • $\begingroup$ That comment leads me to the following solution to get the expected behaviour: Unprotect[CompoundExpression];CompoundExpression[x___]:=Last[Evaluate/@{x}];Protect[CompoundExpression] $\endgroup$
    – celtschk
    Mar 23, 2012 at 7:04
  • $\begingroup$ @Rojo: I just notice that your code assigns Null to a. I guess you meant (a=1)//Null& (but then, Null&[a=1] is shorter and indeed a nice alternative to my ignore function) $\endgroup$
    – celtschk
    Mar 23, 2012 at 7:09
2
$\begingroup$

Maybe this satisfies your request.

$Pre = Function[input, If[input === Null, "Null"; Null, input]];

Basically, $Pre as a function acts on input expression. If the evaluation result of input is Null, then run "Null";Null, so only string "Null" will aggregate in memory for expression ended with ;.

In this way, normal Out[] history(those expression without ;) will retained, while ; terminated expression output will not take up memory. I think this would be better than simply setting $HistoryLength = 0.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.