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 3

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 МБ, но не несколько ГБ, как вы видите). Просто сведение к минимуму, а затем восстановление графического интерфейса освободит этот избыток память.