9
$\begingroup$

Context

I run long Mathematica sessions; sometimes I have Output up to Out[3000+]. Hence I would like to be able to clear out some previous outputs which do use lots of memory.

Attempt

I am aware of clearing some outputs via unprotecting Out as follows

In[1]:= MemoryInUse[]/10^9.

Out[1]= 0.0179439

In[2]:= a = Table[1, {10^8}];
In[3]:= MemoryInUse[]/10^9.

Out[3]= 0.419424

In[4]:= Unprotect[Out];
In[5]:= Out[2] =.
In[6]:= Protect[Out];
In[7]:= MemoryInUse[]/10^9.

Out[7]= 0.0297147

My problem is if I have 3000+ outputs, which one are using a lot of memory so I can decide if it is safe to clear them.

Question

What I am after is a way of finding out which amongst the previous Out are using most of the memory? I would like to have a function, say MemoryHog[n] which would return a list of numbers corresponding to the nth sorted Outputs using most memory.

$\endgroup$
0

2 Answers 2

12
$\begingroup$

This should work

ClearAll[MemoryHog];
MemoryHog[n_] := Module[{list},
   list = {#, ByteCount[Out[#]]} & /@ Range[$Line];
   list=SortBy[list, -Last[#] &];
   list[[1 ;; n]]
];

Now lets test it

(*Some sample input -- evaluate in three cells *)
(*In[3]*)
Range[1000];
(*In[4]*)    
Range[10000];
(*In[5]*)    
Range[100000];

(*  get the hogs*)
MemoryHog[3]
(* ==>
{{5, 400168}, {4, 40168}, {3, 4168}}
*)
$\endgroup$
6
  • $\begingroup$ You remembered $Line before I did, but you seem to have forgotten about SortBy. $\endgroup$
    – Mr.Wizard
    Commented Aug 20, 2012 at 11:06
  • $\begingroup$ True, true, list=SortBy[list, -Last[#] &] would work as well... $\endgroup$
    – Ajasja
    Commented Aug 20, 2012 at 11:16
  • $\begingroup$ Actually better; time it. :-) $\endgroup$
    – Mr.Wizard
    Commented Aug 20, 2012 at 11:18
  • $\begingroup$ Sorry, no time for that now :) I'll take your word for it. $\endgroup$
    – Ajasja
    Commented Aug 20, 2012 at 11:19
  • $\begingroup$ @Ajasja I understand that Instring/@ Transpose[MemoryHog[3]][[1]] would allow me to review the corresponding Inputs. On the other hand its not very readable. Would you know how to print it out as the equivalent of ??In but restricted to the hogs? It would help to decide if they can be cleared without pain. $\endgroup$
    – chris
    Commented Aug 20, 2012 at 11:55
8
$\begingroup$

Why do you have so many Out[] values assigned? This seems like a very poor practice if memory is a concern. I suggest setting something reasonable like $HistoryLength = 3 and finding another way to store your results.

Nevertheless you can find the approximate memory used for each value like this:

Array[{#, ByteCount@Out@#} &, $Line - 1]

This gives output such as:

{{1, 56}, {2, 184}, {3, 6520}}

which are a pairs: {line-number, bytes-used}


It is probably academic now that you know about $HistoryLength, but here is a way to write your "memory hog" function that has some features you may like. It respects $HistoryLength and $Line such that it will not error if you request more Out values than are available, and it returns a Short summary of each Out value.

memoryHog[n_] :=
  Reverse@#[[# ~Ordering~ -Min[n, $HistoryLength, $Line - 1]]] & @ 
    Table[
      {ByteCount@Out@i, i, Short@Out@i},
      {i, Max[1, $Line - $HistoryLength], $Line - 1}
    ] // Column
$\endgroup$
9
  • $\begingroup$ @Wizard I have many Out[] because I do research ;-) i.e. I don't necessarily know where I am going. Or if you prefer I am not a good programmer. Thanks for your answer. $\endgroup$
    – chris
    Commented Aug 20, 2012 at 11:33
  • $\begingroup$ @chris That does not require you to keep all output, does it? Perhaps you should look into a logging method that will write each Out to a file? $\endgroup$
    – Mr.Wizard
    Commented Aug 20, 2012 at 11:36
  • $\begingroup$ I didn't know about the $HistoryLength though. It might do the trick for me. $\endgroup$
    – chris
    Commented Aug 20, 2012 at 11:37
  • $\begingroup$ @Wizard No; typically I don't use any of the outputs. $\endgroup$
    – chris
    Commented Aug 20, 2012 at 11:38
  • $\begingroup$ @chris in that case, certainly set $HistoryLength to a low or zero value in your user init.m file. Ask if you need help with that. $\endgroup$
    – Mr.Wizard
    Commented Aug 20, 2012 at 11:39

Your Answer

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

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