poster
2019-12-10, 16:49
您的心理模型是什么?如何实施?它有哪些优点和缺点? MATLAB GC与Python GC
使用MATLAB嵌套函数在本来看上去很天真的代码中使用时,有时会遇到奇怪的性能瓶颈,我敢肯定这是由于GC。垃圾收集器是VM的重要组成部分,Mathworks并未将其公开。
我的问题是关于MATLAB自己的堆和GC!与处理Java / COM对象无关/防止“内存不足”错误/分配堆栈变量。
编辑:第一个响应实际上是元答案“我为什么要关心?”。我确实很在意,因为GC在实现链接列表 (https://stackoverflow.com/questions/1413860/matlab-linked-list)或MVC (http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller)模式时会表现出来。
回答:
这是我收集的事实清单。在这种情况下,用内存(取消)分配代替GC似乎更合适。
我的主要信息来源是Loren的博客(尤其是其评论)以及MATLAB Digest的这篇 (http://www.mathworks.com/company/newsletters/digest/2008/sept/matlab-objects.html)文章。
由于其面向具有大量数据集的数值计算,MATLAB在优化堆栈对象 (http://mathforum.org/kb/thread.jspa?threadID=265365)性能方面确实做得很好,例如对数据 (http://blogs.mathworks.com/loren/2007/03/22/in-place-operations-on-data/)使用就地操作 (http://blogs.mathworks.com/loren/2007/03/22/in-place-operations-on-data/)以及对函数参数进行按引用 (http://blogs.mathworks.com/loren/2006/05/10/memory-management-for-functions-and-variables/)调用。同样由于其定位,其内存模型与Java之类的OO语言从根本上是不同的 (http://blogs.mathworks.com/loren/2008/03/04/release-r2008a-available/#comment-27674) 。
在版本7之前,MATLAB正式没有用户定义的堆内存(在版本6中, schema.m文件中有未记录的reference功能)。 MATLAB 7具有嵌套函数(闭包)形式和句柄对象 (http://www.c2.com/cgi/wiki?ClosuresAndObjectsAreEquivalent)形式的堆,它们的实现具有相同的基础。附带说明一下,可以在MATLAB中使用闭包来仿真 (http://blogs.mathworks.com/loren/2008/01/16/nested-functions-and-variable-scope/) OO(对于2008a之前的版本很有用)。
出乎意料的是,可以检查由函数句柄(关闭)捕获的封闭函数的整个工作区,请参见MATLAB帮助中的函数function(fhandle) (http://www.mathworks.com/help/techdoc/ref/functions.html) 。这意味着封闭的工作空间正在冻结在内存中。这就是为什么在嵌套函数中使用cellfun/arrayfun有时会非常慢的原因。
Loren (http://blogs.mathworks.com/loren/2008/07/29/understanding-object-cleanup/)和Brad Phelan也有 (http://blogs.mathworks.com/loren/2008/03/10/keeping-things-tidy/)关于对象清理的有趣文章。
在我看来,MATLAB中关于堆释放的最有趣的事实是,每次堆栈被释放时,MATLAB都会尝试执行此操作,即在离开每个函数时。这具有优点, (http://www.mathworks.com/company/newsletters/digest/2008/sept/matlab-objects.html)但是如果堆释放缓慢,则也将带来巨大的CPU损失。在某些情况下,在MATLAB中它实际上非常慢!
可能会击中代码的MATLAB内存释放的性能问题非常严重。我总是注意到,当代码突然运行慢20倍,有时在离开函数和返回调用者之间需要花费几秒钟的时间时,我无意中在代码中引入了循环引用(花费在清理上的时间)。这是一个已知的问题,请参阅Dave Foti (http://blogs.mathworks.com/loren/2008/08/18/when-to-create-classes-in-matlab/#comment-29947)和此较老的论坛帖子 (http://mathforum.org/kb/message.jspa?messageID=6015847&tstart=0) ,其中的代码用于使该图片可视化性能(测试是在不同的机器上进行的,因此不同MATLAB版本的绝对时序比较是没有意义的):
参考对象池大小的线性增加意味着MATLAB性能的多项式(或指数)降低!对于价值对象,其性能是线性的。
考虑到这些事实,我只能推测MATLAB尚未使用非常有效的引用计数形式进行堆释放。
编辑 :我总是遇到许多小的嵌套函数的性能问题,但是最近我注意到,至少在2006a上,清理具有数兆字节数据的单个嵌套范围也是很糟糕的,仅将嵌套范围变量设置为空就需要1.5秒!
编辑2 :终于我得到了答案- 戴夫·福蒂本人 (http://blogs.mathworks.com/loren/2011/03/08/common-design-considerations-for-object-properties/#comment-32092) 。他承认这些缺陷,但表示MATLAB将保留其当前的确定性清除方法。
图例:执行时间越短越好
https://i.stack.imgur.com/FUYi7.gifhttps://i.stack.imgur.com/aqvnK.gifhttps://i.stack.imgur.com/fIt4Y.gif
更多&回答... (https://stackoverflow.com/questions/1446281)
使用MATLAB嵌套函数在本来看上去很天真的代码中使用时,有时会遇到奇怪的性能瓶颈,我敢肯定这是由于GC。垃圾收集器是VM的重要组成部分,Mathworks并未将其公开。
我的问题是关于MATLAB自己的堆和GC!与处理Java / COM对象无关/防止“内存不足”错误/分配堆栈变量。
编辑:第一个响应实际上是元答案“我为什么要关心?”。我确实很在意,因为GC在实现链接列表 (https://stackoverflow.com/questions/1413860/matlab-linked-list)或MVC (http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller)模式时会表现出来。
回答:
这是我收集的事实清单。在这种情况下,用内存(取消)分配代替GC似乎更合适。
我的主要信息来源是Loren的博客(尤其是其评论)以及MATLAB Digest的这篇 (http://www.mathworks.com/company/newsletters/digest/2008/sept/matlab-objects.html)文章。
由于其面向具有大量数据集的数值计算,MATLAB在优化堆栈对象 (http://mathforum.org/kb/thread.jspa?threadID=265365)性能方面确实做得很好,例如对数据 (http://blogs.mathworks.com/loren/2007/03/22/in-place-operations-on-data/)使用就地操作 (http://blogs.mathworks.com/loren/2007/03/22/in-place-operations-on-data/)以及对函数参数进行按引用 (http://blogs.mathworks.com/loren/2006/05/10/memory-management-for-functions-and-variables/)调用。同样由于其定位,其内存模型与Java之类的OO语言从根本上是不同的 (http://blogs.mathworks.com/loren/2008/03/04/release-r2008a-available/#comment-27674) 。
在版本7之前,MATLAB正式没有用户定义的堆内存(在版本6中, schema.m文件中有未记录的reference功能)。 MATLAB 7具有嵌套函数(闭包)形式和句柄对象 (http://www.c2.com/cgi/wiki?ClosuresAndObjectsAreEquivalent)形式的堆,它们的实现具有相同的基础。附带说明一下,可以在MATLAB中使用闭包来仿真 (http://blogs.mathworks.com/loren/2008/01/16/nested-functions-and-variable-scope/) OO(对于2008a之前的版本很有用)。
出乎意料的是,可以检查由函数句柄(关闭)捕获的封闭函数的整个工作区,请参见MATLAB帮助中的函数function(fhandle) (http://www.mathworks.com/help/techdoc/ref/functions.html) 。这意味着封闭的工作空间正在冻结在内存中。这就是为什么在嵌套函数中使用cellfun/arrayfun有时会非常慢的原因。
Loren (http://blogs.mathworks.com/loren/2008/07/29/understanding-object-cleanup/)和Brad Phelan也有 (http://blogs.mathworks.com/loren/2008/03/10/keeping-things-tidy/)关于对象清理的有趣文章。
在我看来,MATLAB中关于堆释放的最有趣的事实是,每次堆栈被释放时,MATLAB都会尝试执行此操作,即在离开每个函数时。这具有优点, (http://www.mathworks.com/company/newsletters/digest/2008/sept/matlab-objects.html)但是如果堆释放缓慢,则也将带来巨大的CPU损失。在某些情况下,在MATLAB中它实际上非常慢!
可能会击中代码的MATLAB内存释放的性能问题非常严重。我总是注意到,当代码突然运行慢20倍,有时在离开函数和返回调用者之间需要花费几秒钟的时间时,我无意中在代码中引入了循环引用(花费在清理上的时间)。这是一个已知的问题,请参阅Dave Foti (http://blogs.mathworks.com/loren/2008/08/18/when-to-create-classes-in-matlab/#comment-29947)和此较老的论坛帖子 (http://mathforum.org/kb/message.jspa?messageID=6015847&tstart=0) ,其中的代码用于使该图片可视化性能(测试是在不同的机器上进行的,因此不同MATLAB版本的绝对时序比较是没有意义的):
参考对象池大小的线性增加意味着MATLAB性能的多项式(或指数)降低!对于价值对象,其性能是线性的。
考虑到这些事实,我只能推测MATLAB尚未使用非常有效的引用计数形式进行堆释放。
编辑 :我总是遇到许多小的嵌套函数的性能问题,但是最近我注意到,至少在2006a上,清理具有数兆字节数据的单个嵌套范围也是很糟糕的,仅将嵌套范围变量设置为空就需要1.5秒!
编辑2 :终于我得到了答案- 戴夫·福蒂本人 (http://blogs.mathworks.com/loren/2011/03/08/common-design-considerations-for-object-properties/#comment-32092) 。他承认这些缺陷,但表示MATLAB将保留其当前的确定性清除方法。
图例:执行时间越短越好
https://i.stack.imgur.com/FUYi7.gifhttps://i.stack.imgur.com/aqvnK.gifhttps://i.stack.imgur.com/fIt4Y.gif
更多&回答... (https://stackoverflow.com/questions/1446281)