打开太多图形时如何避免 MATLAB 崩溃?
Posted
技术标签:
【中文标题】打开太多图形时如何避免 MATLAB 崩溃?【英文标题】:How to avoid MATLAB crash when opening too many figures? 【发布时间】:2011-09-06 06:34:55 【问题描述】:有时我启动一个 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 堆可用,如果没有足够的空间,它会拒绝打开一个新图?
更新
使用下面的答案,我得到了一个关于 Java 有多少可用内存的漂亮图表:
这是使用
制作的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
varargout1=builtin('figure',varargin:);
else
builtin('figure',varargin:);
end
else
if nargout > 0
varargout1=builtin('figure');
else
builtin('figure');
end
end
end
【问题讨论】:
不错的更新。如果可以的话,我会第二次投票赞成。我想知道增加是否可能是由于 Java 分配了更多内存。 【参考方案1】:一般来说,我建议将最大 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 是否会尝试这样做。
【讨论】:
freeMemory 只告诉你现在有多少是免费的,而不是如果你执行一次 GC 会有多少是免费的。【参考方案2】:您可以检查空闲内存,如果没有足够的触发GC并再次检查。如果还不够,就失败。您可能希望留出 1-10 MB 的空间。
你可以使用 Runtime.gc() 和 Runtime.freeMemory();
如果您不设置最大内存,它将使其成为可用内存的百分比。
【讨论】:
GC 总是在 JVM 抛出 OutOfMemory 错误之前自动发生,因此显式调用Runtime.gc()
并不是真正需要释放空间,但肯定有助于获得可用内存的正确数字。需要记住的一点是,VM 决定何时进行 GC,Runtime.gc()
调用并非在所有情况下都会导致垃圾收集发生。
Matlab 会设置程序可用的最大 java 内存,你所能做的就是选择这个应该是多少。【参考方案3】:
我在我自己的函数 'limfig' 中使用了 findobj 函数,其中 imglimit 设置您希望允许一次打开的图形数量。
function y=limfig
imglimit=15;
if length(findobj('type','figure'))<imglimit
y=figure;
else
'too many figures already open'
return
end
end
将此短代码保存为 limfig.m,然后在任何其他代码中使用 f=limfig 行而不是 f=figure。
【讨论】:
以上是关于打开太多图形时如何避免 MATLAB 崩溃?的主要内容,如果未能解决你的问题,请参考以下文章