【问题标题】:MATLAB's Garbage Collector?MATLAB 的垃圾收集器?
【发布时间】:2010-11-29 14:20:41
【问题描述】:

你的心智模式是什么?它是如何实施的?它有哪些优点和缺点? MATLAB GC 与 Python GC?

在看起来无害的代码中使用 MATLAB 嵌套函数时,我有时会看到奇怪的性能瓶颈,我确信这是因为 GC。垃圾收集器是 VM 的重要组成部分,Mathworks 并未将其公开。

我的问题是关于 MATLAB 自己的 heap 和 GC!与处理 Java/COM 对象/防止“内存不足”错误/堆栈变量分配无关。

编辑:第一个响应实际上是元答案“我为什么要关心?”。我很在意,因为 GC 在实现 linked listMVC 模式时会表现出来。

【问题讨论】:

  • Python 实际上没有垃圾收集器。 CPython(您从 python.org 获得的标准参考实现)中的所有内容都是引用计数的。 Matlab也有可能以这种方式实现,但我实际上并不知道。您问这个问题是为了决定是使用 Matlab 还是 Python,还是只是出于好奇?
  • @Levy:我不同意你的观点——引用计数是用于 GC 的机制之一。
  • @Mikhail:关于引用计数是否是垃圾收集的一种形式,我认为没有太大的争论,我认为当你说垃圾收集时,你暗示了标记/清除、复制或混合算法Java 和 .NET 使用。或者至少,这是许多人会接受的方式。

标签: memory-management matlab garbage-collection


【解决方案1】:

这是我收集的事实清单。在这种情况下,术语内存(解除)分配似乎更合适,而不是 GC。

我的主要信息来源是 Loren 的博客(尤其是它的 cmets)和来自 MATLAB Digest 的 this 文章。

由于其面向可能的大型数据集的数值计算,MATLAB 在优化stack objects 性能方面做得非常好,例如在函数参数上使用in-place operations on datacall-by-reference。也因为它的定位,它的内存模型基本上是来自 Java 等面向对象语言的different

MATLAB 在版本 7 之前正式没有用户定义的堆内存(在版本 6 中,schema.m 文件中有未记录的reference 功能)。 MATLAB 7 具有nested functions (closures) and handle objects 形式的堆,它们的实现共享相同的基础。作为旁注,OO 可以是 emulated,在 MATLAB 中带有闭包(对于 2008a 之前的版本很有趣)。

令人惊讶的是,可以检查函数句柄(闭包)捕获的封闭函数的整个工作区,请参阅 MATLAB 帮助中的函数 functions(fhandle)。这意味着封闭的工作空间正在内存中冻结。这就是为什么 cellfun/arrayfun 在嵌套函数中使用时有时会很慢的原因。

LorenBrad Phelan 也有关于对象清理的有趣帖子。

在我看来,关于 MATLAB 中的堆释放最有趣的事实是,每次释放堆栈时,MATLAB 都会尝试执行此操作,即在离开每个函数时。这有advantages,但如果堆释放很慢,这也是一个巨大的 CPU 损失。而且在某些场景下在 MATLAB 中其实是非常慢的!

MATLAB 内存释放的性能问题可能会影响代码,非常糟糕。我总是注意到我无意中在我的代码中引入了一个循环引用,当它突然运行 x20 慢时,有时在离开函数和返回其调用者之间需要几秒钟(花费在清理上的时间)。这是一个已知问题,看Dave Fotithis older forum post这幅图的可视化性能用了哪些代码(测试是在不同的机器上进行的,所以不同MATLAB版本的绝对时序比较没有意义):

引用对象池大小的线性增加意味着 MATLAB 性能的多项式(或指数)下降!正如预期的那样,值对象的性能是线性的。

考虑到这些事实,我只能推测 MATLAB 使用还不是很有效的 引用计数 形式进行堆释放。

编辑:我总是遇到许多小嵌套函数的性能问题,但最近我注意到至少在 2006a 中清理了一个单个嵌套范围 em> 几兆字节的数据也很糟糕,将嵌套范围变量设置为空需要 1.5 秒!

EDIT 2:终于我得到了答案 - by Dave Foti himself。他承认存在缺陷,但表示 MATLAB 将保留其目前的确定性清理方法。

传说:执行时间越短越好

【讨论】:

  • 谢谢,太好了。我很想在新版本的 MATLAB 上看到这个测试的结果。你能分享你的基准代码吗?
  • 图表是否表明 R2008a 中的内存管理比 R2009a 中的要快一些,或者我们无法比较图表之间的值?
【解决方案2】:

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

【讨论】:

  • @Mike:我认为我们可以在 Matlab 中谈论 3 种对象:java、stack 和 heap。你的回答是关于前两个,但我的问题是关于第三个。
  • 这个答案值得更多的支持,因为它提供了有用的信息,而不是 rlbond 的帖子。
  • 对不起,塞西尔,这个答案不是我问题的答案。这只是一些东西,与我的问题无关。这个答案看起来很有启发性,但只是故意分散我所问问题的注意力。
  • 我遇到了我怀疑与对象管理有关的性能问题。 stackoverflow.com/questions/4268113/…
【解决方案3】:

您似乎正在尝试构建某种 Python 与 MATLAB 参数。我对那个论点没那么感兴趣。

您的元问题的元答案。

实际上,你不在乎是相当重要的。当我这么说的时候,我并不是要将它限制在 MATLAB 内存管理上。这扩展到 Python、Java、.NET 和任何其他进行动态内存分配并且仍在积极开发中的语言。

您对当前内存管理机制了解得越多,就越有可能针对该特定实现进行防御性编码,您就越有可能无法从未来的性能改进中受益。在 developerworks.com 上由 Brian Goetz 撰写的 Java 的 gc 中可以找到许多很好的例子:

http://www.ibm.com/developerworks/library/j-jtp01274.html

你可以说知道很重要。我反驳说,这都是关于要求的。更合适的问题是,我正在为我的项目考虑的语言在性能、开发工作、可维护性、可移植性、开发人员的专业知识等方面是否满足我的需求?

我从未见过需要使用分代 gc over mark sweep over ref 计数的项目。我不希望很快看到。

【讨论】:

    猜你喜欢
    • 2018-12-30
    • 1970-01-01
    • 2011-11-07
    • 2013-04-01
    • 2012-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多