减少扩展的Mathematica会话中的内存使用量

时间:2011-07-29 02:03:26

标签: memory-leaks wolfram-mathematica memory-management

我正在做一些相当长的计算,这可能很容易跨越几天。在这些计算过程中,有时Mathematica会耗尽内存。为此,我最终采取了以下措施:

ParallelEvaluate[$KernelID]; (* Force the kernels to launch *)
kernels = Kernels[];

Do[
   If[Mod[iteration, n] == 0,
      CloseKernels[kernels];
      LaunchKernels[kernels];
      ClearSystemCache[]];
   (* Complicated stuff here *)
   Export[...], (* If a computation ends early I don't want to lose past results *)
   {iteration, min, max}]

这很好,但是随着时间的推移主内核会累积内存。目前,我的主要内核占用大约1.4 GB的RAM。有什么方法可以强迫Mathematica清除它正在使用的内存吗?我尝试在我的代码中使用的Share Clear中乱丢ModulesModule,但随着时间的推移,内存似乎仍然存在。

我还试图确保在MemoryConstrained之外没有任何大而复杂的运行,所以某些东西不会在范围内停留太长时间。但即便如此,我仍然有记忆问题。

我能做些什么吗?我总是会使用大量内存,因为我的大部分计算涉及几个大而密集的矩阵(通常是1200 x 1200,但可能更多),所以我对使用{{1}时要小心}。


更新

问题正是Alexey Popkov在答案中所说的。如果使用Module,内存会随着时间缓慢泄漏。在这种情况下,它恰好加剧了,因为我有多个Module[..]语句。 “main”Module位于ParallelTable范围内,其中8个内核同时运行。解决(相对)大量迭代问题,由于Module的错误导致批次内存泄漏的滋生地。

2 个答案:

答案 0 :(得分:10)

由于您广泛使用Module,我认为您可能有兴趣知道this错误与非删除临时Module变量。

示例(不删除未链接的临时变量及其定义):

In[1]:= $HistoryLength=0;
a[b_]:=Module[{c,d},d:=9;d/;b===1];
Length@Names[$Context<>"*"]

Out[3]= 6

In[4]:= lst=Table[a[1],{1000}];
Length@Names[$Context<>"*"]

Out[5]= 1007

In[6]:= lst=.
Length@Names[$Context<>"*"]

Out[7]= 1007

In[8]:= Definition@d$999

Out[8]= Attributes[d$999]={Temporary}

d$999:=9

请注意,在上面的代码中,我设置$HistoryLength = 0;来强调Module的这种错误行为。如果您不这样做,临时变量仍然可以从历史变量(InOut)链接,并且由于这个原因在更广泛的情况下不会被他们的定义删除(它是正如列昂尼德提到的那样,不是一个错误而是一个特征。

更新:仅供记录。 v.5.2中还有另一个旧bug with non-deleting unreferenced Module variables after Part assignments to them,即使在版本7.0.1中也没有完全修复:

In[1]:= $HistoryLength=0;$Version
Module[{L=Array[0&,10^7]},L[[#]]++&/@Range[100];];
Names["L$*"]
ByteCount@Symbol@#&/@Names["L$*"]
Out[1]= 7.0 for Microsoft Windows (32-bit) (February 18, 2009)
Out[3]= {L$111}
Out[4]= {40000084}

答案 1 :(得分:2)

您是否尝试在所有子内核以及主内核中评估$HistoryLength=0;?历史跟踪是内存不足的最常见来源。

您是否尝试过不要使用速度慢,耗费内存的Export并使用快速高效的Put

从您的帖子中您在主内核或子内核中评估ClearSystemCache[]的位置并不清楚?看起来你只在主内核中评估它。在每次迭代之前尝试在所有子内核中对其进行评估。