Как избежать краха MATLAB при открытии слишком большого количества цифр?
Иногда я запускаю MATLAB script и понимаю слишком поздно, что он будет выводить слишком много цифр. В конце концов я получаю
Исключение в потоке "AWT-EventQueue-0" java.lang.OutOfMemoryError: пространство кучи Java
который можно легко воспроизвести на моей машине, используя
for i=1:inf
figure;
end
Я добираюсь до ~ 90 фигур, прежде чем он сработает со стандартной настройкой (Preferences/Java Heap Memory) из 128 куб Java Java, в то время как удвоение кучи до 256 МБ дает мне около 200 цифр.
Вы видите какой-либо способ избежать сообщения об ошибке Java? Если памяти недостаточно для другой фигуры, мне бы хотелось, чтобы мой script рассказывался, а не сбой.
Может быть, у меня может быть оболочка для figure
, которая (как-то?) проверяет, насколько доступна куча Java, и которая отказывается открывать новую фигуру, если осталось мало места?
Обновление
Используя приведенные ниже ответы, я получаю хороший график того, сколько свободной памяти 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
, которое перегружает и вызывает команду build-in 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
Ответы
Ответ 1
В общем, я бы предложил установить максимальную память Java Heap примерно на 25% доступной ОЗУ, что позволяет вам открывать множество цифр (но не бесконечные числа). Если вы не можете сделать это в настройках (например, b/c у вас есть Mac, как у меня), это решение поможет - оно отменяет предпочтение настройки.
Связанное решение также сообщает вам, сколько свободного ява памяти осталось, и сколько всего доступно: Запустите следующие команды:
java.lang.Runtime.getRuntime.maxMemory
java.lang.Runtime.getRuntime.totalMemory
java.lang.Runtime.getRuntime.freeMemory
К сожалению, цифра не занимает фиксированного объема памяти Java, пустая цифра занимает гораздо меньше, чем одна, отображающая 10 тыс. точек, а минимизированная цифра занимает меньше памяти, чем максимальная. Однако, если вы можете оценить среднюю память, необходимую для каждой фигуры, вы действительно можете написать обертку для figure
, которая проверяет, может ли эта цифра быть последней. В качестве альтернативы/дополнительно вы можете заставить функцию обертки свести к минимуму все другие цифры (см. Недокументированный Matlab для этого).
EDIT Как указано @Peter Lawrey, вы также можете попробовать и выполнить сборку мусора, прежде чем проверять, сколько памяти доступно - хотя В любом случае, я не знаю, попытается ли Matlab это сделать.
Ответ 2
Вы можете проверить свободную память, если нет достаточного запуска GC и снова проверить. Если этого еще недостаточно, не получится. Возможно, вы захотите разрешить головную комнату 1-10 МБ.
Вы можете использовать Runtime.gc() и Runtime.freeMemory();
Если вы не установите максимальную память, это сделает ее частью доступной памяти.
Ответ 3
Я использую функцию findobj в своей собственной функции "limfig", где 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.