Как избежать краха 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.