Matlab: свободная память объектов класса
Недавно я написал некоторый код, используя ООП Matlab. В каждом объекте класса я сохраняю некоторые данные измерений в качестве свойства и определяю методы их оценки. При среднем наборе данных один объект класса использует около 32 МБ памяти. Теперь я пишу графический интерфейс, который должен обрабатывать эти объекты.
На первом шаге я загружаю набор объектов из сохраненного .mat-файл (около 200 объектов, 2 ГБ на жестком диске)и хранить их в структуре handles. Они заполняют оперативную память и используют около 6-7 ГБ, когда нагруженный. Это не проблема.
Но если я закрываю графический интерфейс, кажется, что я не могу освободить используемую память. Я пробовал разные подходы, но безуспешно.
Установка полей данных "пустыми" в деструкторе класса:
function delete(obj)
obj.timeVector = [];
obj.valueVector = [];
end
Попытка освободить его в figure_CloseRequestFcn:
function figure_CloseRequestFcn(hObject, eventdata, handles)
handles.data = [];
handles = rmfield(handles,'data');
guidata(hObject,handles);
clear handles;
pack; %Matlab issues a warning, that pack could only
%be used from the command line, but that did
%not work either
delete(hObject);
end
Есть идеи, кроме закрытия Matlab каждый раз после работы с GUI?
3 ответа:
Я нашел ответ в центре отчетов об ошибках Matlab. Кажется, существует с R2011b.
Резюме
Хранение объектов в MAT-файлах может вызвать утечку памяти и предотвратить очистку класса объектов
Описание
После сохранения экземпляра класса MyClass в файле MAT вызов clear classes может привести к появлению предупреждения:
Предупреждение: объекты класса MyClass существуют. Не удается очистить этот класс или любой из его надклассы.
Это предупреждение сохраняется, даже если вы очистили все экземпляры класса в рабочей области. Предупреждение может появиться для одного формата MAT-файла,а не для другого.
Обходной путь
При некоторых обстоятельствах переключение на другой формат файла MAT может устранить предупреждение.
Http://www.mathworks.ch/support/bugreports/857319
Править: Я пробовал старые форматы для сохранения, но это тоже не работает. Я получаю " ошибку закрытие файла" (http://www.mathworks.ch/matlabcentral/answers/18098-error-using-save-error-closing-file) таким образом, Matlab не поддерживает сохранение объектов класса так хорошо. Тогда мне придется жить с проблемами памяти и перезапускать Matlab после каждого использования GUI.
Основываясь на ваших скриншотах
memory
, определенно есть память, которая не очищается. Есть небольшой шанс, что вы нашли фундаментальный недостаток в сборке мусора Matlab, но гораздо более вероятно, что ~6gig резидентных данных памяти все еще доступны через некоторые серии ссылок. Основываясь на личном опыте, вот несколько способов, которыми память, которую вы считали очищенной, все еще может быть доступна:
Объекты таймера: если один из обратного вызова функции таймера ссылаются на эти данные (или копию), то эти данные все еще доступны. Вам нужно позвонить
deleted(t)
по этому таймеру.Постоянные переменные в функциях: я часто кэширую данные в постоянной переменной внутри функции, это явно позволяет получить доступ к этим данным в будущем, поэтому они не будут очищены. Вам нужно вызвать
clear FUNCTIONNAME
, чтобы очистить связанные постоянные переменные.В объектах GUI, как в данных, так и в функциях обратного вызова: фигуры и любые настойчивые люди должны быть очищены.
Любые статические методы или постоянные атрибуты в классах, которые могут сохранять данные. Они могут быть очищены либо индивидуально внутри класса, либо с помощью силы, используя
clear CLASSNAME
.Некоторые советы по поиску устаревшей ссылки на данные (опять же, на основе личных ошибок)
Посмотрите на точное количество байтов, потерянных после каждого вызова, используя вызов
x=memory;
, чтобы получить точное количество. Она последовательна? Это число, что вы узнаешь? Иногда я могу найти утечку, поняв, что это ровно 238263232 байта, следовательно, двойной массив 29782904, который должен быть из функции xyz.Посмотрите, какие классы на самом деле удаляются. В пределах вашей функции
delete(obj)
Добавьте подробное отображение или какие объекты удаляются, а какие нет. Для данного неотделенного объекта, откуда он может быть ссылкой? Вам не нужно очищать данные в функцииdelete(obj)
, Как вы это делаете, Matlab должен справиться с этим за вас. Вместо этого используйте функциюdelete
в качестве средства отладки.
В Matlab естьсборщик мусора , поэтому вам не нужно вручную управлять памятью. После закрытия графического интерфейса вся память будет освобождена, за исключением того, что находится в вашем рабочем пространстве. Вы можете очистить переменные рабочей области с помощью
clear
.Одна вещь, которую я заметил в Windows (не уверен в других платформах), заключается в том, что графический интерфейс Matlab иногда сохраняет дополнительную память (возможно, 100 МБ, но не несколько ГБ, как вы видите). Просто сведение к минимуму, а затем восстановление графического интерфейса освободит этот избыток память.