有时我启动了一个 MATLAB 脚本,但为时已晚才意识到它将输出太多的数字。最终我得到了一个
Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
可以很容易地在我的机器上复制
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
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),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 是否会尝试这样做。
关于java - 打开太多图形时如何避免 MATLAB 崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6201272/