Сокращение использования памяти в расширенной сессии Mathematica - PullRequest
14 голосов
/ 29 июля 2011

Я делаю довольно длинные вычисления, которые могут легко занять несколько дней.В ходе этих вычислений иногда 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 ГБ ОЗУ.Могу ли я заставить Mathematica очистить память, которую она использует?Я пытался засорять Share и Clear во многих Modules, которые я использую в своем коде, но со временем кажется, что память все еще увеличивается.

Я пытался также сделатьЯ уверен, что у меня нет ничего большого и сложного, работающего за пределами Module, так что что-то не остается слишком долго.Но даже с этим у меня все еще есть проблемы с памятью.

Могу ли я что-нибудь сделать с этим?У меня всегда будет большой объем используемой памяти, так как в большинстве моих расчетов используются несколько больших и плотных матриц (обычно 1200 x 1200, но может быть и больше), поэтому я осторожен с использованием MemoryConstrained.


Обновление:

Проблема была именно в том, что Алексей Попков заявил в своем ответе.Если вы используете Module, память будет медленно течь со временем.Это обострилось в этом случае, потому что у меня было несколько Module[..] заявлений.«Основной» Module находился в пределах ParallelTable, где одновременно работало 8 ядер.Придерживайтесь (относительно) большого количества итераций, и это стало почвой для лотов утечек памяти из-за ошибки с Module.

Ответы [ 2 ]

10 голосов
/ 29 июля 2011

Поскольку вы широко используете Module, я думаю, что вам может быть интересно узнать эту ошибку с удалением временных 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) и не будут удалены с их определениями по этой причине в более широком наборе случаев (это не ошибка, но особенность, как упоминал Леонид).

ОБНОВЛЕНИЕ: Только для записи. Есть еще одна старая ошибка , связанная с невозможностью удаления не связанных ссылок Module переменных после Part присвоений им в v.5.2, которая не полностью исправлена ​​даже в версии 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}
2 голосов
/ 31 июля 2011

Вы пытались оценить $HistoryLength=0; во всех подядрах, а также в главном ядре? Отслеживание истории является наиболее распространенным источником выхода из памяти.

Вы пытались не использовать медленный и занимающий много памяти Export и использовать вместо этого быстрый и эффективный Put?

Из вашего поста не понятно, где вы оцениваете ClearSystemCache[] - в главном ядре или в подядрах? Похоже, вы оцениваете это только в главном ядре. Попробуйте оценить его во всех подъядерах перед каждой итерацией.

...