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

时间:2011-06-01 12:38:47

标签: java matlab heap-memory jvm-crash

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

  

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

可以使用

在我的机器上轻松复制
for i=1:inf
  figure;
end

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

您是否看到避免 Java错误消息?如果没有足够的内存用于其他人物,我希望我的脚本为告诉而不是崩溃。

也许我可以拥有figure的包装器(以某种方式?)检查有多少Java堆可用,如果没有足够的空间,它会拒绝打开一个新的数字?

更新

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

figure;plot(freeMem/1E6,'x');ylabel('java.lang.Runtime.getRuntime.freeMemory [MB]');xlabel('number of empty figures created');

这是使用

制作的
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 < memcutoff 
    fprintf('Free memory is low (%1.0f Bytes) -> 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 < memkeyboard
    warning('jb:fig:lowjavamem','Java memory very low -> going into interactive mode. Good luck!');
    keyboard;
end
if freemem < memcutoff
    warning('jb:fig:lowjavamem','Java memory low -> 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

2 个答案:

答案 0 :(得分:6)

一般情况下,我建议将最大Java堆内存设置为可用RAM的25%左右,这样可以打开大量数字(但不是无限数字)。如果你不能在首选项中执行此操作(例如,b / c,你有像我的Mac),this solution将有所帮助 - 它会覆盖首选项设置。

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

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

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

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

答案 1 :(得分:2)

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

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

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