Хорошая часть этой "потерянной" памяти, вероятно, связана с фрагментацией памяти. Когда Matlab выделяет и освобождает массивы в течение сеанса, память разбивается на более мелкие области, а часть теряется из-за накладных расходов в диспетчере памяти как на уровне Matlab, так и на нижележащих уровнях C. Служебная нагрузка не считается Matlab как «используемая», поскольку она не используется для хранения значений массива M-кода. Некоторая память может также потребляться Matlab, загружая дополнительные M-файлы и библиотеки, выделяя внутренние буферы или структуры, или расширением кучи Java во встроенной JVM Matlab. Это нормально. После некоторой работы у Matlab будет не так много памяти, как в новой сессии.
AFAIK, когда происходит низкоуровневая фрагментация, вы ничего не можете сделать, чтобы устранить ее, кроме перезапуска Matlab. Выделение большого количества маленьких массивов может ускорить фрагментацию. Это иногда случается, если вы используете большие ячейки или большие массивы объектов. Поэтому, если у вас возникли проблемы, вам может понадобиться уменьшить пиковое использование памяти в функции, разбив работу на меньшие куски, уменьшив использование ячеек и так далее. И если у вас есть большие массивы cellstr в файлах MAT, преобразуйте их в char. «Верхний предел» распределения - это то, что управляет фрагментацией, поэтому, если вы можете разбить свой набор данных на более мелкие порции, вы можете разместить его в меньшем объеме памяти.
Внутри вашей функции очистите как можно больше из одного файла MAT, прежде чем переходить к следующему. Один из способов сделать это неявно - переместить обработку каждого файла в подфункцию, если она в данный момент находится в цикле в вашей главной функции.
Чтобы помочь отладке, выполните "dbstop if all error", которая будет вызвана OOM. Оттуда вы можете использовать whos и отладчик, чтобы узнать, где занято место, когда вы исчерпываете память. Это может выявить временные переменные, которые необходимо очистить, или предложить способы разбиения работы.
Если вы хотите поэкспериментировать, чтобы увидеть, как выглядит фрагментация и как она влияет на вывод memory (), вот функция, которая просто создаст некоторую фрагментацию.
function fragmem(nbytes, chunksize)
%FRAGMEM Fragment the Matlab session's memory
if nargin < 2; chunksize = 1*2^10; end
nbytes = nbytes - rem(nbytes, chunksize);
nsteps = 100; % to make initial input relatively small
c = cell([1 nsteps]);
stepsize = nbytes / nsteps;
chunksperstep = ceil(stepsize / chunksize);
fprintf('Fragmenting %d MB memory into %d KB chunks (%d steps of %d chunks)\n',...
round(nbytes/2^20), round(chunksize/2^10), nsteps, chunksperstep);
x = zeros([1 chunksperstep * chunksize], 'uint8');
colsizes = repmat(chunksize, [1 chunksperstep]);
for i = 1:nsteps
c{i} = mat2cell(x, 1, colsizes);
end
Фрагментация 300 МБ порциями по 1 КБ на моей машине приводит к «потере» на моей машине win32 размера, который вы видите.
>> memory
Maximum possible array: 1384 MB (1.451e+009 bytes) *
Memory available for all arrays: 1552 MB (1.627e+009 bytes) **
Memory used by MATLAB: 235 MB (2.463e+008 bytes)
Physical Memory (RAM): 3311 MB (3.472e+009 bytes)
>> fragmem(300*2^20)
Fragmenting 300 MB memory into 1 KB chunks (100 steps of 3072 chunks)
>> memory
Maximum possible array: 1009 MB (1.059e+009 bytes) *
Memory available for all arrays: 1175 MB (1.232e+009 bytes) **
Memory used by MATLAB: 257 MB (2.691e+008 bytes)
Physical Memory (RAM): 3311 MB (3.472e+009 bytes)
>>