Matlab:类对象的自由内存



我最近使用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将释放多余的内存。

最新更新