我必须将一个应用程序作为独立的Matlab可执行文件提供给客户端。该代码包括对内部创建多个单元阵列的函数的一系列调用。
我的问题是,当响应用户负载的增加而对此函数的调用次数增加时,会发生内存不足错误。我想这是低级别内存碎片,因为工作区变量与循环次数无关。
正如前面提到的here,退出并重新启动Matlab是目前此类内存不足错误的唯一解决方案。
我的问题是我如何在独立应用程序中实现这样的机制来保存数据,在出现内存不足错误的情况下退出并重新启动(或者以某种方式预测出这种错误的可能性很高)。
有没有最佳做法?
感谢。
答案 0 :(得分:2)
这有点困难。您是否可以更改代码以将工作分解为块以使其更高效,而不是寻求重新启动以清除问题?碎片大部分与峰值单元相关的内存使用量成正比,数据项的大小变化多少,并且随着时间的推移总量减少。如果你可以将大量工作分成小块,那么这可以降低碎片内存使用量的“高水位线”。您还可以使用共享其后备数据值的“flyweight”数据结构来节省内存使用量,或者有时将基于单元格的结构转换为引用对象或数字代码。您能与我们分享您的代码和数据结构示例吗?
理论上,您可以通过将工作空间和相关状态保存到mat文件并让可执行文件启动另一个自身实例来重新加载该状态并继续执行,然后让原始可执行文件退出。但就用户体验和调试能力而言,这将非常难看。
另一种选择是将高碎片代码卸载到另一个可以被杀死并重新启动的工作进程,而主要的可执行进程仍然存在。如果你有并行计算工具箱,现在可以编译成独立的Matlab可执行文件,这将非常简单:打开一个或两个工作者的工作池,并使用同步调用运行其中的碎片代码,定期查杀工人并培养新的。工作者是独立的进程,从非碎片的内存空间开始。如果您没有PCT,您可以将您的应用程序编译为两个独立的应用程序 - 驱动程序应用程序和工作者应用程序 - 并让主应用程序启动工作人员并通过IPC控制它,来回传递您的数据作为MAT文件或字节流。不过,这对代码来说并不会很有趣。
也许您也可以将一些脆弱的代码推送到Java层,Java层可以更优雅地处理类似于细胞的数据结构。
首先将代码更改为更少的碎片可能是更简单,更简单的方法,并导致应用程序设计不那么复杂。根据我的经验,这通常是可能的。如果您分享一些代码和数据结构细节,我们可以提供帮助。
答案 1 :(得分:2)
另一个选择是使用chkmem等函数定期检查内存碎片。
您可以集成此函数,以便在每次迭代时对您进行静默调用,或使用timer
对象每隔X分钟调用一次...
这个想法是使用这些未记录的函数feature memstats
和feature dumpmem
来获得除当前分配的最大变量之外可用的最大可用内存块。使用它你可以猜测是否有内存碎片的迹象。
检测到时,您会警告用户并指导他们如何保存当前会话(导出到MAT文件),重新启动应用程序,并在重新启动时恢复会话。