Jon*_*erg 15 java matlab heap-memory jvm-crash
有时我会启动一个MATLAB脚本并意识到太晚了,它会输出太多的数字.最终我得到了一个
线程"AWT-EventQueue-0"中的异常java.lang.OutOfMemoryError:Java堆空间
这可以很容易地在我的机器上使用
for i=1:inf
figure;
end
Run Code Online (Sandbox Code Playgroud)
在使用128 MB Java堆的标准设置(首选项/ Java堆内存)崩溃之前,我得到大约90个数字,而将堆加倍到256 MB则给出了大约200个数字.
您是否看到了避免 Java错误消息的方法?如果没有足够的内存供另一个人使用,我希望我的脚本能够被告知而不是崩溃.
也许我可以有一个包装器figure(以某种方式?)检查有多少Java堆可用,如果没有足够的空间,它会拒绝打开一个新的数字?
更新
使用下面的答案,我得到了一个很好的图表,说明Memory Java有多少可用内容:
![figure; plot(freeMem/1E6,'x'); ylabel('java.lang.Runtime.getRuntime.freeMemory [MB]'); xlabel('创建的空数字');](https://i.stack.imgur.com/EMnHC.png)
这是使用
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
Run Code Online (Sandbox Code Playgroud)
我假设开头的增加意味着垃圾收集每次调用它时只会做一些努力吗?
更新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
Run Code Online (Sandbox Code Playgroud)
一般来说,我建议将最大Java堆内存设置为可用RAM的大约25%,这允许您打开大量数字(但不是无限数字).如果您不能在首选项中执行此操作(例如,b/c,您有像我一样的Mac),此解决方案将有所帮助 - 它会覆盖首选项设置.
链接的解决方案还会告诉您剩余的可用Java内存量以及可用总量:运行以下命令:
java.lang.Runtime.getRuntime.maxMemory
java.lang.Runtime.getRuntime.totalMemory
java.lang.Runtime.getRuntime.freeMemory
Run Code Online (Sandbox Code Playgroud)
不幸的是,一个数字不占用固定数量的Java内存,一个空数字比一个显示10k点少得多,而最小化数字比最大化数字占用更少的内存.但是,如果你可以估计每个数字所需的平均内存,你确实可以编写一个包装器来figure检查这个数字是否可能是最后一个.或者/另外,您可以使包装函数最小化所有其他数字(请参阅未记录的Matlab).
编辑正如@Peter Lawrey指出的那样,在检查可用内存量之前,您也可以尝试执行垃圾收集 - 尽管我不知道Matlab是否会尝试这样做.
| 归档时间: |
|
| 查看次数: |
9152 次 |
| 最近记录: |