Java 当打开太多数字时,如何避免MATLAB崩溃?
有时,我启动一个MATLAB脚本,但意识到它将输出太多的数字太晚了。最终我得到了一份工作 线程“AWT-EventQueue-0”java.lang.OutOfMemoryError中出现异常:java堆空间 可以在我的机器上使用Java 当打开太多数字时,如何避免MATLAB崩溃?,java,matlab,heap-memory,jvm-crash,Java,Matlab,Heap Memory,Jvm Crash,有时,我启动一个MATLAB脚本,但意识到它将输出太多的数字太晚了。最终我得到了一份工作 线程“AWT-EventQueue-0”java.lang.OutOfMemoryError中出现异常:java堆空间 可以在我的机器上使用 for i=1:inf figure; end 在128 MB Java堆的标准设置()崩溃之前,我得到了大约90个数字,而将堆加倍到256 MB会得到大约200个数字 您是否找到了避免Java错误消息的方法?如果没有足够的内存存储另一个图形,我希望我的脚本能够
for i=1:inf
figure;
end
在128 MB Java堆的标准设置()崩溃之前,我得到了大约90个数字,而将堆加倍到256 MB会得到大约200个数字
您是否找到了避免Java错误消息的方法?如果没有足够的内存存储另一个图形,我希望我的脚本能够被告知,而不是崩溃
也许我可以为figure
创建一个包装器,它(不知怎么的?)检查有多少Java堆可用,如果没有足够的空间,它会拒绝打开一个新的figure
更新
使用下面的答案,我可以得到一个很好的图表,显示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
函数varargout=图(varargin)
memcutoff=10E6;%至少保留此数量的可用字节
memkeyboard=3E6;%如果内存低于此值,请中断执行并转到键盘模式
全球垃圾新数字
如果拒绝新的数字
警告('jb:fig:lowjavamem2','Java内存不足->拒绝创建新图形。若要重置,请键入“全局拒绝新图形;拒绝新图形=[];”);
返回
结束
freemem=java.lang.Runtime.getRuntime.freeMemory;
如果freemem正在运行garbace收集器…\n',freemem);
java.lang.Runtime.getRuntime.gc
结束
freemem=java.lang.Runtime.getRuntime.freeMemory;
%fprintf('可用内存为%1.0f字节。\n',freemem);
如果freemem进入交互模式。祝你好运!');
键盘
结束
如果freemem拒绝创建新图形!');
拒绝新数字=正确;
其他的
如果nargin>0
如果nargout>0
varargout{1}=builtin('figure',varargin{:});
其他的
内置('figure',varargin{:});
结束
其他的
如果nargout>0
varargout{1}=内置('figure');
其他的
内置(“图”);
结束
结束
结束
一般来说,我建议将最大Java堆内存设置为可用RAM的25%左右,这样可以打开很多数字(但不是无限数字)。如果您不能在首选项中执行此操作(例如,b/c您有一台像我一样的Mac),将有帮助-它将覆盖首选项设置
链接的解决方案还告诉您还有多少可用java内存,以及总共有多少可用内存:运行以下命令:
java.lang.Runtime.getRuntime.maxMemory
java.lang.Runtime.getRuntime.totalMemory
java.lang.Runtime.getRuntime.freeMemory
不幸的是,一个图形不需要固定的Java内存,一个空的图形比一个显示10k点的图形占用更少的内存,一个最小化的图形比一个最大化的图形占用更少的内存。但是,如果您可以估计每个图所需的平均内存,那么您确实可以为图
编写一个包装器,检查这个图是否可能是最后一个。或者/另外,您可以使包装器函数最小化所有其他图形(为此)
编辑正如所指出的,您也可以在检查可用内存量之前尝试执行垃圾收集-尽管我不知道Matlab是否会尝试这样做。如果没有足够的触发GC,您可以检查可用内存并再次检查。如果仍然不够,就失败。您可能希望允许1-10 MB的主机空间 您可以使用Runtime.gc()和Runtime.freemory()
如果不设置最大内存,它将占可用内存的百分比。我在自己的函数“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
函数y=limfig
imglimit=15;
如果length(findobj('type','figure')freemory只告诉您现在有多少可用空间,而不是如果您执行了GC,那么会有多少可用空间。GC总是在JVM抛出OutOfMemory错误之前自动发生,因此,显式调用Runtime.GC()
并不是真正需要释放空间的,但这肯定有助于获得正确的可用内存数据。需要记住的一点是,VM决定何时进行GC,Runtime.GC()
调用并不会在任何情况下都导致垃圾收集。Matlab将为程序设置最大可用java内存,我们所能做的就是选择该内存的大小。更新很好。如果可以的话,我会第二次投票。我想知道这是否是因为Java分配了更多的内存。