2013-02-12 75 views
3

我最近用Matlab的OOP编写了一些代码。在每个类对象中,我将一些测量数据保存为属性并定义评估它们的方法。对于平均数据集,一个类对象使用大约32 MB的内存。 现在我正在编写一个应该处理这些对象的GUI。Matlab:类对象的自由存储器

在第一步中,我从已保存的.mat文件(大约200个对象,2GB硬盘上)加载一组对象,并将它们存储在句柄结构中。它们填充RAM并在加载时使用大约6-7 GB。这没有问题。

但是,如果我关闭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 

任何想法,除了后关闭Matlab的每一次使用GUI?

+0

你确定内存仍然被阻塞,而不是只显示被占用?所以如果你使用正常数量的内存,你会用完吗?此外,我只能想到“清除所有”,但没有太多的希望。 – 2013-02-12 13:57:40

+0

所以我假设它只是由Matlab保留,但如果另一个程序需要更多的RAM,Matlab会将其设置为空闲的?我试图退出GUI,启动另一个RAM密集型程序,停止后,Matlab似乎释放了一些保留的内存(请参阅链接)。我只是感到困惑,因为通常在GUI /脚本/函数退出后,Matlab的内存使用量降至正常的“空闲”使用率。 http://i.stack.imgur.com/zWrcu.png – idono 2013-02-12 15:07:59

+0

在使用GUI之前,使用过程中以及使用GUI之后,“内存”命令的结果是什么? – Pursuit 2013-02-12 15:57:51

回答

2

我在Matlab Bug中心找到了答案。似乎自R2011b以来存在。

摘要

存储在MAT文件对象可以从被清除

说明

存储类的一个实例后导致内存泄漏和防止对象类,' MyClass'在MAT文件中调用清除类可能会导致警告:

警告:'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。

+0

你有没有考虑为你的班级重载'load'和'save'?只保存类的属性(实际数据),然后创建一个构造函数,给出这个结构构建整个类实例? – Shai 2013-02-14 13:25:56

+0

@Shai我没有想到,但数据结构是:'struct.classObject.data'。除了不同类型的类对象之外,结构本身还有其他信息。我必须重载'struct'的保存/加载,或者编写一个额外的函数来将整个数据结构分解为单个部分并再次编写它们。我认为这样做太费劲了,因为它非常复杂。但是,感谢这个想法。 – idono 2013-02-14 13:44:32

+0

如果您执行'struct(myClassInstance)',会发生什么? – Shai 2013-02-14 13:48:45

-1

Matlab有一个garbage collector所以你不需要手动管理内存。关闭GUI之后,除了工作区中的内容外,所有内存都将被释放。您可以使用clear清除工作区变量。我在Windows上注意到的一件事(不确定其他平台)是Matlab的GUI有时会保留额外的内存(可能是100 MB,但不是像你所看到的那样是多GB)。简单地最小化然后恢复GUI将释放这多余的内存。

1

根据您的memory屏幕截图,确实存在未被清除的内存。在Matlab的垃圾收集中发现一个基本缺陷的可能性很小,但是~6Gig的内存驻留数据实际上仍然可以通过一系列链接获得。根据个人经验,这里有一些方法是您所想的内存被清理仍然可以提供:

  • Timer对象:如果定时器的回调函数一个引用这个数据(或复印件) ,那么这些数据仍然可用。您需要在该计时器上拨打deleted(t)

  • 函数中的持久变量:我经常将数据缓存在函数内的一个持久变量中,这显然允许将来访问该数据,所以它不会被清除。您需要拨打clear FUNCTIONNAME清除关联的持久变量。

  • 在GUI对象中,无论是数据还是回调函数:数字和任何persist都需要清除。

  • 任何可以保留数据的类中的静态方法或常量属性。这些可以在班级内单独清除,也可以使用clear CLASSNAME强制清除。

一些技巧寻找过时的链接数据(再次,根据个人的错误)

  • 看的确切字节数在每次通话后丢失,使用x=memory;呼吁得到确切数量。它一致吗?这是你认识的一个数字吗?有时我发现它确实是238263232字节后才能找到泄漏,因此必须使用函数xyz中的29782904双数组。

  • 查看哪些类实际上被删除。在delete(obj)函数中,添加一个详细的显示或者哪些对象正在被删除,并且通过推理,哪些不是。对于给定的非删除对象,它可以从哪里引用?您应该不需要像delete(obj)函数那样清除数据,Matlab应该为您处理。使用delete函数作为调试工具。

+0

我缩小了它的范围。它不是GUI本身,而是保存/加载。由于文件的大小,我只是在工作区中从头开始创建对象,并使用'-v7.3格式'保存它们。清理工作区正常工作,为每个对象调用析构函数并释放内存。从hdd重新加载相同的对象后,清除不起作用,发出警告:存在'ClassName'类的对象。无法清除此类或其任何超类。对每个对象使用'delete(classObj)'调用析构函数,但不释放内存。 – idono 2013-02-13 08:46:21