你的心理模型是什么?它是如何实现的?它有哪些优点和缺点? MATLAB GC与Python GC ?
在使用MATLAB嵌套函数时,我有时会看到奇怪的性能瓶颈,但我确信这是因为GC。垃圾收集器是VM的重要组成部分,Mathworks不会将其公开。
我的问题是关于MATLAB自己的堆和GC!不是关于Java / COM对象的处理/防止“内存不足”错误/堆栈变量的分配。
编辑:第一个回复实际上是元回答“我为什么要关心?”。我很关心,因为GC在实施linked list或MVC模式时会表现出来。
答案 0 :(得分:44)
这是我收集的事实清单。在这种情况下, memory(de)allocation 这个术语似乎更合适,而不是GC。
我的主要信息来源是Loren的博客(特别是其评论)和MATLAB Digest的this文章。
由于MATLAB具有可能的大数据集的数值计算方向,因此MATLAB在优化stack objects性能方面做得非常好,例如在函数参数上使用in-place operations on data和call-by-reference。另外,由于它的定位,它的内存模型基本上是来自Java等OO语言的different。
在版本7之前,MATLAB正式没有用户定义的堆内存(在版本6中reference
文件中有未记录的schema.m
功能。 MATLAB 7以nested functions (closures) and handle objects的形式堆积,它们的实现共享相同的基础。作为旁注,OO可以是emulated,在MATLAB中有闭包(对于2008a之前的版本很有趣)。
令人惊讶的是,可以检查由函数句柄(闭包)捕获的封闭函数的整个工作空间,请参阅MATLAB帮助中的函数functions(fhandle)。这意味着封闭工作区在内存中冻结。这就是cellfun/arrayfun
在嵌套函数中使用时有时非常慢的原因。
Loren和Brad Phelan也有关于对象清理的有趣帖子。
在我看来,MATLAB中有关堆重新分配的最有趣的事实是,每次堆栈被释放时,MATLAB都会尝试这样做,即在离开每个函数时。这有advantages但如果堆释放缓慢,也会造成巨大的CPU损失。在某些情况下,它在MATLAB中实际上非常慢!
可以命中代码的MATLAB内存释放的性能问题非常糟糕。我总是注意到我在代码中无意中引入了循环引用,当它突然运行x20较慢时,有时需要几秒钟才能离开函数并返回其调用者(清理所花费的时间)。这是一个已知问题,请参阅Dave Foti和this older forum post使用哪些代码使图片可视化性能(测试在不同的机器上进行,因此不同MATLAB版本的绝对时序比较毫无意义):
参考对象的池大小的线性增加意味着MATLAB性能的多项式(或指数)减少!对于值对象,性能如预期的那样是线性的。
考虑到这些事实,我只能推测MATLAB使用的还不是非常有效的引用计数形式进行堆释放。
编辑:我总是遇到许多小型嵌套函数的性能问题,但最近我注意到至少在2006a中清理了一个单个嵌套范围有几兆字节的数据也很糟糕,将嵌套的范围变量设置为空需要1.5秒!
编辑2 :最后我得到了答案 - by Dave Foti himself。他承认存在缺陷,但表示MATLAB将保留其目前的确定性清理方法。
图例:缩短执行时间
答案 1 :(得分:13)
MATLAB在工作区浏览器中或使用“whos”命令使工作区非常清晰。这将显示命令创建的所有对象以及它们占用的内存量。
feature('memstats')
将向您展示MATLAB可用的最大连续内存块,这意味着它是您可以创建的最大矩阵。使用“clear”命令将同步从内存中删除这些对象并释放空间以便再次使用。
JVM仅处理Java项的垃圾收集。因此,如果您在编辑器中打开文件并关闭它,Java会负责从内存中删除窗口和文本等。如果在MATLAB工作区中创建一个Java对象,首先必须将其清除,然后由jvm清理它。
我们的技术说明中有很多关于管理程序内存的信息:http://www.mathworks.com/support/tech-notes/1100/1106.html
我最近写过关于在MATLAB桌面博客上处理Java内存的文章:http://blogs.mathworks.com/desktop/2009/08/17/calling-java-from-matlab-memory-issues/
如果你在学术上感兴趣,当函数退出或调整变量大小时分配的内存会发生什么......我很确定这是一个商业秘密,它会改变每个版本。您永远不会注意到它,如果遇到您怀疑与对象管理相关的性能问题,请提供技术支持的帮助凭证:http://www.mathworks.com/support
答案 2 :(得分:2)
您似乎正在尝试构建某种Python与MATLAB参数。我对那个论点不感兴趣。
对元提问的元回答。
你不在乎,这实际上非常重要。当我这样说时,我并不是要将其限制在MATLAB内存管理中。这扩展到Python,Java,.NET和任何其他执行动态内存分配的语言,并且仍在积极开发中。
您对内存管理的当前机制了解得越多,就越有可能针对该特定实现进行防御性编码,您越不可能从未来的性能改进中受益。可以在developerWorks.com上由Brian Goetz编写的Java的gc中找到一些很好的例子:
http://www.ibm.com/developerworks/library/j-jtp01274.html
你可以说知道很重要。我反驳说这完全是关于要求的。更合适的问题是,我正在为我的项目考虑的语言是否满足我在性能,开发工作,可维护性,可移植性,开发人员的专业知识等方面的需求?
我从来没有见过一个项目要求使用世代gc而不是标记扫描而不是引用计数。我不希望很快看到一个。