7
$\begingroup$

Unlike using

Unprotect[In,Out];
Clear[In,Out];
Protect[In,Out];

to clean the occupied memory of the whole notebook, I want to clean the memory dynamically and accurately. That is, I want to clean out the specific memory I assign whenever I need.

For example, I wrote a loop and at each loop, it generates some intermediate results that need not to be stored and I just want to clean its corresponding memory at the end of each loop. How can I achieve it ?

For example,

For[i=0,i<=100,i++,
    x=Array[#&,{1000,1000}];(*occupy many memory*)
    Total[x];
    (*after the Total operation, the x is worthless now
      so I want to clean out its memory
      How should I do*)
    ]
$\endgroup$
2
  • 4
    $\begingroup$ Your best bet is to not use stateful code (variables and assignments), if that can be avoided (and in most cases it can) - then the memory will be claimed automatically by garbage collector. If you use mutable variables, localize them (with Module, for example, or in some cases Block), then those variables will also be cleared automatically at the end (except in a few pathological cases which you are unlikely to hit in practice). $\endgroup$ May 29, 2015 at 15:22
  • 4
    $\begingroup$ One thing to remember is that the kernel stores previous results by default in Out[n]. You can control the number of stored results by adjusting HistoryLength. $\endgroup$
    – Yves Klett
    May 29, 2015 at 15:50

2 Answers 2

5
$\begingroup$

You can use Block for this purpose. From Mathematica documentation:

When you execute a block, values assigned to x, y, ... are cleared. When the execution of the block is finished, the original values of these symbols are restored.

For the example you gave, you should use something like:

Clear[x]
For[i=0,i<=100,i++,
     totalx = Block[{x},
                        x=Array[#&,{1000,1000}];
                        Total[x]
                    ]
     (*do something with totalX*)
]

Benchmarking

Using MemoryInUse[], before and after executing the code, testing with an Array of 10,000 x 1,000, I ran the following code:

a = 1; (* to make sure the Kernel is up and running *)
memBefore = MemoryInUse[]
  (* ... the For loop ... with Array[#&,{10000,1000}] *)
memAfter = MemoryInUse[]
extraMemUsed = memAfter - memBefore;
N[extraMemUsed/1024/1024] (* in MB *)

Starting with a fresh kernel each time, the original code leaves the kernel with extra 78 MB of memory usage, whereas the code using Block leaves the kernel with only 0.2 MB of extra memory usage.

$\endgroup$
1
$\begingroup$

Apply the Clear function to a symbol to clear values and definitions for that symbol, e.g.:

Clear[x]
$\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.