我正在做一些相当长的计算,这可能很容易跨越几天。在这些计算过程中,有时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
中乱丢Modules
和Module
,但随着时间的推移,内存似乎仍然存在。
我还试图确保在MemoryConstrained
之外没有任何大而复杂的运行,所以某些东西不会在范围内停留太长时间。但即便如此,我仍然有记忆问题。
我能做些什么吗?我总是会使用大量内存,因为我的大部分计算涉及几个大而密集的矩阵(通常是1200 x 1200,但可能更多),所以我对使用{{1}时要小心}。
更新
问题正是Alexey Popkov在答案中所说的。如果使用Module
,内存会随着时间缓慢泄漏。在这种情况下,它恰好加剧了,因为我有多个Module[..]
语句。 “main”Module
位于ParallelTable
范围内,其中8个内核同时运行。解决(相对)大量迭代问题,由于Module
的错误导致批次内存泄漏的滋生地。
答案 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
的这种错误行为。如果您不这样做,临时变量仍然可以从历史变量(In
和Out
)链接,并且由于这个原因在更广泛的情况下不会被他们的定义删除(它是正如列昂尼德提到的那样,不是一个错误而是一个特征。
更新:仅供记录。 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[]
的位置并不清楚?看起来你只在主内核中评估它。在每次迭代之前尝试在所有子内核中对其进行评估。