分析 Mathematica 中的内存使用情况
除了为 Eclipse 插件(mathematica workbench、iirc)支付 $$$ 费用之外,还有什么方法可以分析 mathkernel 内存使用情况(具体到各个变量)?
现在,我完成了一个需要多 GB 内存的程序的执行,但唯一存储的内容最多应该是 ~50MB 的数据,但 mathkernel.exe 往往会保留 ~1.5GB(基本上,Windows 会存储的数据最多)给它)。除了保存我需要的数据并每次退出内核之外,还有其他更好的方法来解决这个问题吗?
编辑:我刚刚了解了 ByteCount 函数(它在基本数据类型上显示了一些令人不安的结果,但这不是重点),但即使是我所有变量的总和也远不及 mathkernel 所取的量。什么给?
Is there any way to profile the mathkernel memory usage (down to individual variables) other than paying $$$ for their Eclipse plugin (mathematica workbench, iirc)?
Right now I finish execution of a program that takes multiple GB's of ram, but the only things that are stored should be ~50MB of data at most, yet mathkernel.exe tends to hold onto ~1.5GB (basically, as much as Windows will give it). Is there any better way to get around this, other than saving the data I need and quitting the kernel every time?
EDIT: I've just learned of the ByteCount function (which shows some disturbing results on basic datatypes, but that's besides the point), but even the sum over all my variables is nowhere near the amount taken by mathkernel. What gives?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
许多用户没有意识到的一件事是,将所有输入和输出存储在
输入
和输出< /code>
符号,无论您是否将输出分配给变量。
Out
也别名为%
,其中%
是前一个输出,%%
是第二个输出最后等等。%123
相当于Out[123]
。如果您没有使用
%
的习惯,或者只使用几个级别的深度,请设置$HistoryLength
为 0 或一个小的正整数,以仅保留Out.
您可能还想查看函数
MaxMemoryUsed
和MemoryInUse
。当然,
$HistoryLength
问题可能是也可能不是您的问题,但您还没有分享您的实际评估是什么。如果您能够发布它,也许有人能够更多地解释为什么它如此占用内存。
One thing a lot of users don't realize is that it takes memory to store all your inputs and outputs in the
In
andOut
symbols, regardless of whether or not you assign an output to a variable.Out
is also aliased as%
, where%
is the previous output,%%
is the second-to-last, etc.%123
is equivalent toOut[123]
.If you don't have a habit of using
%
, or only use it to a few levels deep, set$HistoryLength
to 0 or a small positive integer, to keep only the last few (or no) outputs around inOut
.You might also want to look at the functions
MaxMemoryUsed
andMemoryInUse
.Of course, the
$HistoryLength
issue may or not be your problem, but you haven't shared what your actual evaluation is.If you're able to post it, perhaps someone will be able to shed more light on why it's so memory-intensive.
这是我对内存使用情况进行分析的解决方案:
上面的评估给出了下表:
Here is my solution for profiling of memory usage:
Evaluation the above gives the following table:
Michael Pilat 的答案是一个很好的答案,
MemoryInUse< /code> 和
MaxMemoryUsed
可能是您拥有的最好的工具。ByteCount
很少有帮助,因为它测量的结果可能会被大大高估,因为它忽略共享子表达式,并且通常会忽略无法通过 Mathematica 函数直接访问的内存,而 Mathematica 函数通常是内存使用情况。在某些情况下,您可以做的一件事是使用
分享
< /a> 函数,在可能的情况下强制共享子表达式。在某些情况下,这可以节省数十甚至数百兆字节。您可以通过在使用Share
之前和之后使用MemoryInUse
来判断它的工作情况。此外,一些看似无害的事情可能会导致 Mathematica 使用比您预期更多的内存。连续的机器实数数组(并且仅机器实数)可以被分配为所谓的“压缩”数组,就像 C 或 Fortran 分配它们的方式一样。但是,如果数组中混合了机器实数和其他结构(包括符号),则所有内容都必须是 “装箱”,数组就变成了指针数组,这会增加很多开销。
Michael Pilat's answer is a good one, and
MemoryInUse
andMaxMemoryUsed
are probably the best tools you have.ByteCount
is rarely all that helpful because what it measures can be a huge overestimate because it ignores shared subexpressions, and it often ignores memory that isn't directly accessible through Mathematica functions, which is often a major component of memory usage.One thing you can do in some circumstances is use the
Share
function, which forces subexpressions to be shared when possible. In some circumstances, this can save you tens or even hundreds of magabytes. You can tell how well it's working by usingMemoryInUse
before and after you useShare
.Also, some innocuous-seeming things can cause Mathematica to use a whole lot more memory than you expect. Contiguous arrays of machine reals (and only machine reals) can be allocated as so-called "packed" arrays, much the way they would be allocated by C or Fortran. However, if you have a mix of machine reals and other structures (including symbols) in an array, everything has to be "boxed", and the array becomes an array of pointers, which can add a lot of overhead.
一种方法是在内存不足时自动重新启动内核。您可以在从内核中执行消耗内存的代码,而主内核仅获取计算结果并控制内存使用。
One way is to automatize restarting of kernel when it goes out of memory. You can execute your memory-consuming code in a slave kernel while the master kernel only takes the result of computation and controls memory usage.