你对它的心理模型是什么?它是如何实施的?它有哪些优势和劣势?MatLab GC与PythonGC?
当在原本看起来无害的代码中使用MATLAB嵌套函数时,我有时会看到奇怪的性能瓶颈,我确信这是因为GC。垃圾收集器是VM的重要组成部分,Mathworks没有公开它。
我的问题是关于MatLab自己的堆和GC!不是关于Java/COM对象的处理/防止“内存不足”错误/堆栈变量的分配。
**EDIT:**第一个响应实际上是元答案:我为什么要关心?我确实关心,因为GC在实现linked list或MVC模式时会显示自己。
3条答案
按热度按时间ghhkc1vu1#
这是我收集的事实清单。在这种情况下,术语内存(释放)分配似乎比GC更合适。
我的主要信息来源是Loren的博客(特别是它的评论)和来自MatLab Digest的this文章。
由于它面向可能存在大量数据集的数值计算,因此在优化stack objects性能方面做得非常好,比如在函数参数上使用in-place operations on data和call-by-reference。此外,由于它的方向性,它的内存模型与Java等面向对象语言有根本的不同。
在版本7之前,MatLab正式没有用户定义的堆内存(在版本6中,
schema.m
文件中有未记录的reference
功能)。MatLab 7具有nested functions (closures) and handle objects形式的堆,它们的实现共享相同的基础。作为附注,OO可以是带有闭包的emulated(对于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中,清理单个嵌套作用域和一些MB的数据也很糟糕,仅将嵌套作用域变量设置为空就需要1.5秒!
编辑2:我终于得到了答案--戴夫·福蒂本人。他承认存在缺陷,但他表示,matlab将保留目前的确定性清理方法。
传说:执行时间越短越好
sy5wg1nm2#
在Workspace浏览器中或使用“Whos”命令时,MatLab可以使工作区非常清晰。这将显示您的命令创建的所有对象以及它们占用的内存量。
将向您显示可用于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
sulc1iza3#
看起来您似乎是在尝试构建某种类型的PythonvsMatLab参数。我对那个论点不是很感兴趣。
对你的元问题的元回答。
事实上,你不关心这一点是相当重要的。当我这么说的时候,我并不是想把它限制在matlab内存管理上。这扩展到了Python、Java、.NET和任何其他执行动态内存分配且仍在积极开发中的语言。
您对当前内存管理机制了解得越多,就越有可能针对该特定实现编写防御性代码,就越有可能无法从未来的性能改进中获益。在由Brian Goetz在developerworks.com上出色地撰写的Java GC中,可以找到许多这样的好例子:
http://www.ibm.com/developerworks/library/j-jtp01274.html
你可以说知道这一点很重要。我反驳说,这一切都是关于要求的。更恰当的问题是,我正在为我的项目考虑的语言在性能、开发工作量、可维护性、可移植性、开发人员的专业知识等方面是否满足我的需求?
我从来没有见过一个项目需要使用代际GC,而不是Mark Sweep,而不是引用计数。我不指望很快就能看到一个。