在Mathematica中分析内存使用情况

时间:2010-08-05 20:28:10

标签: profiling memory-management wolfram-mathematica

除了为他们的Eclipse插件(mathematica workbench,iirc)支付$$$之外,有没有办法分析mathkernel内存使用情况(下至个别变量)?

现在我完成了一个占用多GB GB的程序的执行,但是存储的唯一东西最多应该是~50MB的数据,但是mathkernel.exe往往保持在~1.5GB(基本上,同样多因为Windows会给它)。有没有更好的方法来解决这个问题,除了保存我需要的数据并每次退出内核?

编辑:我刚刚了解了ByteCount函数(它显示了基本数据类型的一些令人不安的结果,但除此之外),但即使是所有变量的总和也远不及mathkernel所采用的数量。是什么给了什么?

4 个答案:

答案 0 :(得分:12)

许多用户没有意识到的一件事是,无论是否将输出分配给InOut符号,都需要内存来存储所有输入和输出一个变量。 Out的别名为%,其中%是前一个输出,%%是倒数第二个,等等%123相当于Out[123] {1}}。

如果您没有使用%的习惯,或者仅将其用于几个级别,请将$HistoryLength设置为0或小的正整数,以仅保留最后几个(或者没有)Out周围的输出。

您可能还想查看函数MaxMemoryUsedMemoryInUse

当然,$HistoryLength问题可能与您的问题有关,但您尚未分享您的实际评估结果。 如果你能够发布它,也许有人能够更清楚地了解为什么它会占用大量内存。

答案 1 :(得分:7)

这是我的内存使用情况分析解决方案:

myByteCount[symbolName_String] := 
  Replace[ToHeldExpression[symbolName], 
   Hold[x__] :> 
    If[MemberQ[Attributes[x], Protected | ReadProtected], 
     Sequence @@ {}, {ByteCount[
       Through[{OwnValues, DownValues, UpValues, SubValues, 
          DefaultValues, FormatValues, NValues}[Unevaluated@x, 
         Sort -> False]]], symbolName}]];

With[{listing = myByteCount /@ Names[]},
 Labeled[Grid[Reverse@Take[Sort[listing], -100], Frame -> True, 
   Alignment -> Left], 
  Column[{Style[
     "ByteCount for symbols without attributes Protected and \
ReadProtected in all contexts", 16, FontFamily -> "Times"], 
    Style[Row@{"Total: ", Total[listing[[All, 1]]], " bytes for ", 
       Length[listing], " symbols"}, Bold]}, Center, 1.5], Top]]

评价上面给出了下表:

screenshot

答案 2 :(得分:4)

迈克尔·皮拉特的answer是一个很好的,MemoryInUseMaxMemoryUsed可能是你拥有的最好的工具。 ByteCount很少有用,因为它测量的内容可能是一个巨大的高估,因为它忽略了共享的子表达式,并且它经常忽略不能通过Mathematica函数直接访问的内存,而Mathematica函数通常是内存使用的主要组成部分。

在某些情况下,您可以做的一件事是使用Share函数,它可以在可能的情况下强制共享子表达式。在某些情况下,这可以为您节省数十甚至数百兆字节。您可以在使用MemoryInUse之前和之后使用Share来判断它的工作情况。

此外,一些看似无害的东西会导致Mathematica使用比预期更多的内存。机器实数的连续数组(以及机器实数)可以被分配为所谓的“打包”数组,就像它们由C或Fortran分配的方式一样。但是,如果在阵列中混合使用机器实数和其他结构(包括符号),则所有内容都必须为"boxed",并且数组将成为指针数组,这会增加很多开销。

答案 3 :(得分:2)

一种方法是在内存不足时自动重启内核。您可以在从属内核中执行占用内存的代码,而主内核只获取计算结果并控制内存使用量。