2010-03-05 72 views
15

如果我聲明一個對象是句柄的子類 classdef obj <句柄 我的對象現在基本上是某個指向某個內存某處的「指針」。我如何知道我的對象使用了多少內存?如何判斷句柄對象在matlab中使用多少內存

例如,說我有一個類Foo有場酒吧

classdef foo < handle 
properties 
    bar = randn(1000); 
end 

欄佔用8兆字節(8個字節* 1萬個號碼)

,但如果我鍵入

obj = foo(); 
whos('obj'); 

我得到

Name  Size   Bytes Class Attributes 

    obj  1x1    60 foo     

如何找出obj指向的內存總量?

回答

11

作爲黑客,將其轉換爲結構,看看佔用了多少空間。我認爲這會暴露「常規」對象字段中的所有數據。

f = foo(); 
origWarn = warning(); 
warning off 'MATLAB:structOnObject' 
s = builtin('struct', f); % use 'builtin' in case @foo overrides struct() 
warning(origWarn); 

然後你可以在whos中看到它。

>> whos 
    Name  Size    Bytes Class  Attributes 

    f   1x1     60 foo     
    s   1x1    8000124 struct  

這只是一階近似。它會告訴你它的字段使用了多少內存。如果它們中的任何一個包含句柄對象,則需要遞減該結構的字段並將任何其他句柄對象轉換爲結構來計算其字段。 (如果你想包含Java對象的內存,你還需要一個單獨的函數來估計它們的存儲大小,可能不值得費心。)現在Matlab已經關閉了,函數句柄也可能包含數據;如果要計算封閉數據,則需要使用函數()進行插入。

如果您使用的是句柄對象,那麼在M代碼級別上可能會出現別名和循環引用,所以在遞歸時您需要注意這一點。 (對不起,我不知道如何在新的OO系統中處理這個問題。)

whos中的內存顯示還會對通過Matlab的寫時複製優化共享內存的數組進行雙計數。這是一個具體的例子。

x = NaN(1,10000); 
s.x = x; 
s.y = x; 
s.z = x; 


>> whos 
    Name  Size    Bytes Class  Attributes 

    s   1x1    240372 struct    
    x   1x10000    80000 double    

實際上,s僅消耗約80K;它只包含三個指向x的指針。而80K與X本身消耗的80K相同。除非你修改它們中的任何一個;然後分配一個新的數組。 Whos()不會讓你區分這些情況。處理這個很難; AFAIK唯一的方法是使用MEX文件來獲取mxarray的數據指針,並自己遍歷對象樹,檢測別名指針並計算別名字節。

這是測量內存中對象大小時可能共享組件的一般問題。它們不是離散的物理對象。至少你不在C中,使用指向任意內存塊的指針。

+0

謝謝!這是一個非常好的建議。 一個問題,因爲我不明白matlab如何決定分配新的內存和複製:將foo轉換爲一個結構佔用多少內存?換句話說,如果foo有1 GB的字段,將其轉換爲結構會導致MATLAB消耗額外的GB內存? – Marc 2010-03-05 22:07:49

+0

你會如何評估Java對象的大小? - 這些在Matlab中報告爲0字節... – 2010-03-06 16:46:25

+0

@Marc:將foo轉換爲結構體將不會佔用太多內存。只是結構本身被轉換。結構字段的內容(包括假設的1 GB字段)將使用matlab的寫時複製優化來共享。 – 2010-03-08 22:44:15

2

我剛剛發現的一個簡單方法是Dmitry Borovoy暗示here。我想在這裏提供。

從提供方法的基類中派生您的類,該方法從其所有屬性收集數據。代碼取自上面的給定鏈接。

function total_mem = get_mem(obj) 
     %// Get all properties 
     props = properties(obj); 

     total_mem = 0; 
     %// Loop properties 
     for ii=1:length(props) 
      %// Make shallow copy 
      curr_prop = obj.(props{ii}); %#ok<*NASGU> 
      %// Get info struct for current property 
      s = whos('curr_prop'); 
      %// Add to total memory consumption 
      total_mem = total_mem + s.bytes; 
     end 
    end 

使用範例:

>> fprintf('%.1f MB in use.\n',do.sde.get_mem/1024^2) 
7413.0 MB in use. 
+0

我認爲這不適用於遞歸或嵌套句柄,但這是一個很好的建議 – Marc 2015-04-01 15:09:05