2013-02-12 73 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