我最近使用Matlab的OOP编写了一些代码。在每个类对象中,我将一些测量数据保存为一个属性,并定义评估它们的方法。对于平均数据集,一个类对象使用大约32MB的内存。现在我正在编写一个GUI来处理这些对象。
在第一步中,我从保存的.mat文件中加载一组对象(大约200个对象,硬盘上2GB),并将它们存储在handles结构中。它们填充RAM,加载时使用大约6-7GB。这没问题。
但是,如果我关闭GUI,似乎无法释放使用过的内存。我尝试了不同的方法,但没有成功。
在类的析构函数中将数据字段设置为"空":
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
除了每次使用GUI后都关闭Matlab之外,还有什么想法吗?
我在Matlab错误报告中心找到了答案。似乎存在于R2011b之后。
摘要
在MAT文件中存储对象可能会导致内存泄漏,并阻止对象类被清除
描述
在MAT文件中存储类的实例"MyClass"后,调用clear类可能会导致警告:
警告:存在"MyClass"类的对象。无法清除此类或其任何超类。
即使您已经清除了工作区中该类的所有实例,此警告仍然存在。警告可能发生在一种MAT文件格式上,而不是另一种。
解决方案
在某些情况下,切换到不同的MAT文件格式可能会消除警告。
http://www.mathworks.ch/support/bugreports/857319
编辑:我尝试了旧的保存格式,但这也不起作用。我收到一个"关闭文件时出错"(http://www.mathworks.ch/matlabcentral/answers/18098-error-using-save-error-closing-file)。所以Matlab不支持保存类对象。我将不得不忍受内存问题,然后在每次使用GUI后重新启动Matlab。
根据您的memory
屏幕截图,肯定有内存没有被清除。您很可能在Matlab的垃圾收集中发现了一个根本缺陷,但更可能的是,内存驻留数据的~6Gigs实际上仍然可以通过一些系列链接获得。根据个人经验,以下是一些你认为已经清除的记忆仍然可用的方法:
-
计时器对象:如果计时器的某个回调函数引用了此数据(或副本),则该数据仍然可用。您需要在该计时器上调用
deleted(t)
。 -
函数中的持久变量:我经常将数据缓存在函数中的一个持久变量中,这显然允许将来访问该数据,因此它不会被清除。您需要调用
clear FUNCTIONNAME
来清除关联的持久变量。 -
在GUI对象中,作为数据或回调函数:需要清除图形和任何持久性。
-
类中可以保留数据的任何静态方法或常量属性。这些可以在类中单独清除,也可以使用
clear CLASSNAME
强制清除。
查找数据陈旧链接的一些提示(再次,基于个人错误)
-
查看每次调用后丢失的确切字节数,使用
x=memory;
调用获取确切计数。是否一致?这是一个你能认出的数字吗?有时我会在意识到它正好是238263232字节后发现泄漏,因此是29782904双数组,它必须来自函数xyz。 -
查看哪些类实际被删除。在
delete(obj)
函数中添加一个详细的显示,或者哪些对象正在被删除,通过推断,哪些对象没有被删除。对于给定的未删除对象,它可以从哪里引用?您不需要像现在这样清除delete(obj)
函数中的数据,Matlab应该为您处理这些数据。请使用delete
函数作为调试工具。
Matlab有一个垃圾收集器,因此您不需要手动管理内存。关闭GUI后,除了工作区中的内存外,所有内存都将被释放。可以使用clear
清除工作空间变量。
我在Windows上注意到的一件事(不确定其他平台)是,Matlab的GUI有时会保留额外的内存(可能是100MB,但不是像你看到的那样多GB)。简单地最小化然后恢复GUI将释放多余的内存。