# Memory Management

MemoryInUse[] | number of bytes of memory currently being used by the Wolfram System |

MaxMemoryUsed[] | maximum number of bytes of memory used by the Wolfram System in this session |

Particularly for symbolic computations, memory is usually the primary resource which limits the size of computations you can do. If a computation runs slowly, you can always potentially let it run longer. But if the computation generates intermediate expressions which simply cannot fit in the memory of your computer system, then you cannot proceed with the computation.

The Wolfram System is careful about the way it uses memory. Every time an intermediate expression you have generated is no longer needed, the Wolfram System immediately reclaims the memory allocated to it. This means that at any point in a session, the Wolfram System stores only those expressions that are actually needed; it does not keep unnecessary objects which have to be "garbage collected" later.

In[1]:= |

Out[1]= |

In[2]:= |

Out[2]= |

In[3]:= |

Out[3]= |

In[4]:= |

In[5]:= |

Out[5]= |

In[6]:= |

Out[6]= |

One issue that often comes up is exactly how much memory the Wolfram System can actually use on a particular computer system. Usually there is a certain amount of memory available for *all* processes running on the computer at a particular time. Sometimes this amount of memory is equal to the physical number of bytes of RAM in the computer. Often, it includes a certain amount of "virtual memory", obtained by swapping data on and off a mass storage device.

When the Wolfram System runs, it needs space both for data and for code. The complete code of the Wolfram System is typically several megabytes in size. For any particular calculation, only a small fraction of this code is usually used. However, in trying to work out the total amount of space available for Wolfram System data, you should not forget what is needed for Wolfram Language code. In addition, you must include the space that is taken up by other processes running in the computer. If there are fewer jobs running, you will usually find that your job can use more memory.

It is also worth realizing that the time needed to do a calculation can depend very greatly on how much physical memory you have. Although virtual memory allows you in principle to use large amounts of memory space, it is usually hundreds or even thousands of times slower to access than physical memory. As a result, if your calculation becomes so large that it needs to make use of virtual memory, it may run *much* more slowly.

MemoryConstrained[expr,b] | try to evaluate expr, aborting if more than b additional bytes of memory are requested |

MemoryConstrained[expr,b,failexpr] | return failexpr if the memory constraint is not met |

Memory‐constrained computation.

MemoryConstrained works much like TimeConstrained. If more than the specified amount of memory is requested, MemoryConstrained attempts to abort your computation. As with TimeConstrained, there may be some overshoot in the actual amount of memory used before the computation is aborted.

ByteCount[expr] | the maximum number of bytes of memory needed to store expr |

LeafCount[expr] | the number of terminal nodes in the expression tree for expr |

Finding the size of expressions.

Although you may find ByteCount useful in estimating how large an expression of a particular kind you can handle, you should realize that the specific results given by ByteCount can differ substantially from one version of the Wolfram System to another.

Another important point is that ByteCount always gives you the *maximum* amount of memory needed to store a particular expression. Often the Wolfram System will actually use a much smaller amount of memory to store the expression. The main issue is how many of the subexpressions in the expression can be *shared*.

In an expression like , the two subexpressions are identical, but they may or may not actually be stored in the same piece of computer memory. ByteCount gives you the number of bytes needed to store expressions with the assumption that no subexpressions are shared. You should realize that the sharing of subexpressions is often destroyed as soon as you use an operation like the operator.

Nevertheless, you can explicitly tell the Wolfram Language to share subexpressions using the function Share. In this way, you can significantly reduce the actual amount of memory needed to store a particular expression.

Share[expr] | share common subexpressions in the storage of expr |

Share[] | share common subexpressions throughout memory |

On most computer systems, the memory used by a running program is divided into two parts: memory explicitly allocated by the program, and "stack space". Every time an internal routine is called in the program, a certain amount of stack space is used to store parameters associated with the call. On many computer systems, the maximum amount of stack space that can be used by a program must be specified in advance. If the specified stack space limit is exceeded, the program usually just exits.

In the Wolfram System, one of the primary uses of stack space is in handling the calling of one Wolfram Language function by another. All such calls are explicitly recorded in the Wolfram System Stack discussed in "The Evaluation Stack". You can control the size of this stack by setting the global parameter $RecursionLimit. You should be sure that this parameter is set small enough that you do not run out of stack space on your particular computer system.