2010-03-05 13 views
15

ein Handle-Objekt verwendet in Matlab sagen, wenn ich ein Objekt deklarieren. Wie finde ich heraus, wie viel Speicher mein Objekt verbraucht?Wie kann ich, wie vielen Speicher

Zum Beispiel sagen, dass ich eine Klasse Foo mit einer Feldleiste haben

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

bar nimmt 8 Megabyte (8 Byte * 1 Million Zahlen)

aber wenn ich tippe

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

ich

Name  Size   Bytes Class Attributes 

    obj  1x1    60 foo     

Wie finde ich heraus, wie viel totaler Speicherobj aufzeigt?

Antwort

11

Als ein hack, wandeln Sie es in eine Struktur um und sehen Sie, wie viel Platz belegt ist. Ich denke, das wird alle Daten in "normalen" Objektfeldern offen legen.

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

Dann können Sie es in whos sehen.

>> whos 
    Name  Size    Bytes Class  Attributes 

    f   1x1     60 foo     
    s   1x1    8000124 struct  

Dies ist nur eine Näherung erster Ordnung. Es wird Ihnen sagen, wie viel Speicher seine Felder verwenden. Wenn einige von ihnen Handle-Objekte enthalten, müssen Sie die Felder dieser Struktur rekursiv konvertieren und alle anderen Handle-Objekte in struct konvertieren, um ihre Felder zu zählen. (Wenn Sie den Speicher von Java-Objekten einbeziehen möchten, benötigen Sie außerdem eine separate Funktion, um deren Speichergröße zu schätzen. Wahrscheinlich hat sich die Mühe nicht gelohnt.) Da Matlab jetzt Closures hat, können Funktions-Handles auch Daten enthalten. Sie müssen diejenigen, die Funktionen verwenden(), wenn Sie geschlossene Daten zählen möchten.

Wenn Sie mit Handle-Objekten arbeiten, haben Sie möglicherweise Aliasing- und sogar Zirkelverweise auf M-Code-Ebene, auf die Sie bei der Rekursion achten sollten. (Entschuldigung, ich weiß nicht, wie ich das im neuen OO-System handhaben soll.)

Die Speicheranzeige in whos wird auch Arrays doppelt zählen, die Speicher über Matlabs Copy-on-Write-Optimierung teilen. Hier ist ein konkretes Beispiel.

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    

In Wirklichkeit verbraucht s nur ungefähr 80K; Es enthält nur drei Zeiger auf x. Und diese 80K sind die gleichen 80K, die x selbst verbraucht. Es sei denn, Sie ändern irgendwelche von ihnen; dann wird ein neues Array zugewiesen. Whos() lässt Sie diese Fälle nicht unterscheiden. Das zu handhaben ist hart; AFAIK der einzige Weg, dies zu tun ist, eine MEX-Datei zu verwenden, um die Datenzeiger der mxarray zu erhalten und den Objektbaum selbst zu gehen, Alias-Zeiger zu erkennen und die aliasierten Bytes zu zählen.

Dies ist ein generelles Problem beim Messen der Größe von Objekten im Speicher, wenn ihre Komponenten gemeinsam genutzt werden können. Sie sind keine diskreten physischen Objekte. Zumindest sind Sie nicht in C und arbeiten mit Zeigern auf beliebige Speicherblöcke.

+0

Dank! Das ist ein wirklich guter Vorschlag. Eine Frage, weil ich nicht verstehe, wie Matlab beschließt, neuen Speicher zuzuweisen und zu kopieren: Wie viel Speicher wird foo in eine Struktur umwandeln? Mit anderen Worten: Wenn foo ein 1-GB-Feld hat, wird MATLAB durch die Umwandlung in eine Struktur eine zusätzliche GB Speicher verbrauchen. – Marc

+0

Wie schätzen Sie die Größe von Java-Objekten ein? - Diese werden in Matlab mit 0 Bytes gemeldet ... –

+0

@Marc: Die Konvertierung von foo in eine Struktur wird nicht viel Speicher verbrauchen. Nur die Struktur selbst wird konvertiert. Der Inhalt der Felder der Struktur, einschließlich des hypothetischen 1-GB-Feldes, wird jeweils unter Verwendung der Kopier-bei-Schreib-Optimierung von Matlab gemeinsam genutzt. –

2

Ein einfacher Weg, den ich gerade gefunden habe, ist Dmitry Borovoy schlägt here vor. Ich wollte es hier zur Verfügung stellen.

Leiten Sie Ihre Klasse von einer Basisklasse ab, die eine Methode bereitstellt, die Daten aus all ihren Eigenschaften sammelt. Code nehmen von gegebenem Link oben.

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 

Verwendungsbeispiel:

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

Ich denke, das wird nicht für rekursive oder verschachtelte Griffe funktionieren, aber es ist ein netter Vorschlag – Marc