打开太多数字时如何避免MATLAB崩溃?

有时我会启动一个MATLAB脚本并意识到太晚了,它会输出太多数字。 最终我得到了一个

线程“AWT-EventQueue-0”中的exceptionjava.lang.OutOfMemoryError:Java堆空间

这可以很容易地在我的机器上使用

for i=1:inf figure; end 

在使用128 MB Java堆的标准设置( 首选项/ Java堆内存 )崩溃之前,我得到大约90个数字,而将堆加倍到256 MB则给出了大约200个数字。

您是否看到了避免 Java错误消息的方法? 如果没有足够的内存供另一个人使用,我希望我的脚本能够被告知而不是崩溃。

也许我可以有一个figure包装器(不知何故?)检查有多少Java堆可用,如果没有足够的空间,哪些拒绝打开一个新数字?

更新

使用下面的答案,我得到了一个很好的图表,说明了有多少可用的内存Java:

figure; plot(freeMem / 1E6,'x'); ylabel('java.lang.Runtime.getRuntime.freeMemory [MB]'); xlabel('创建的空数字');

这是使用

 for i=1:inf java.lang.Runtime.getRuntime.gc fprintf('%3.0f: %1.0f Byte free\n',i,java.lang.Runtime.getRuntime.freeMemory); figure; end 

我假设开头的增加意味着垃圾收集每次调用它时只会做一些努力吗?

更新2 – 我的解决方案

使用我在这里获得的帮助,我实现了以下解决方案作为figure.m ,它重载并调用内置figure命令:

 function varargout=figure(varargin) memcutoff = 10E6; % keep at least this amount of bytes free memkeyboard= 3E6; % if memory drops below this, interrupt execution and go to keyboard mode global refuse_new_figures if refuse_new_figures warning('jb:fig:lowjavamem2','Java WAS memory low -> refusing to create a new figure. To reset, type "global refuse_new_figures ; refuse_new_figures = [];"'); return end freemem=java.lang.Runtime.getRuntime.freeMemory; if freemem  running garbace collector...\n',freemem); java.lang.Runtime.getRuntime.gc end freemem=java.lang.Runtime.getRuntime.freeMemory; % fprintf('Free memory is %1.0f Bytes.\n',freemem); if freemem  going into interactive mode. Good luck!'); keyboard; end if freemem  refusing to create a new figure!'); refuse_new_figures=true; else if nargin > 0 if nargout > 0 varargout{1}=builtin('figure',varargin{:}); else builtin('figure',varargin{:}); end else if nargout > 0 varargout{1}=builtin('figure'); else builtin('figure'); end end end 

一般来说,我建议将最大Java堆内存设置为可用RAM的大约25%,这允许您打开大量数字(但不是无限数字)。 如果您不能在首选项中执行此操作(例如,b / c,您有像我一样的Mac), 此解决方案将有所帮助 – 它会覆盖首选项设置。

链接的解决方案还会告诉您剩余的可用Java内存量以及可用总量:运行以下命令:

 java.lang.Runtime.getRuntime.maxMemory java.lang.Runtime.getRuntime.totalMemory java.lang.Runtime.getRuntime.freeMemory 

不幸的是,一个数字不占用固定数量的Java内存,空数比显示10k点的数字少得多,而最小化数字占用的内存少于最大数据。 但是,如果你可以估计每个数字所需的平均内存,你确实可以为figure写一个包装器来检查这个数字是否可能是最后一个。 另外/另外,您可以使包装函数最小化所有其他数字( 请参阅未记录的Matlab )。

编辑正如@Peter Lawrey指出的那样,在检查可用内存量之前,您也可以尝试执行垃圾收集 – 尽管我不知道Matlab是否会尝试这样做。

如果没有足够的触发GC并且再次检查,您可以检查可用内存。 如果仍然不够,那就失败了。 您可能希望允许1-10 MB的头部空间。

您可以使用Runtime.gc()和Runtime.freeMemory();

如果未设置最大内存,则会使其占可用内存的百分比。

我在我自己的函数’limfig’中使用了findobj函数,其中imglimit设置了一次允许打开的数字量。

 function y=limfig imglimit=15; if length(findobj('type','figure')) 

将此短代码保存为limfig.m,然后在任何其他代码中使用行f = limfig而不是f = figure。