How to get size of an object

569 Ansichten (letzte 30 Tage)
Dmitry Borovoy
Dmitry Borovoy am 31 Aug. 2011
Kommentiert: Ivan Garcia am 3 Jan. 2023
There is function 'whos' that shows variables and their sizes, but for objects it shows just size of the pointer (about 112 bytes). How to get real size of the object?

Akzeptierte Antwort

Dmitry Borovoy
Dmitry Borovoy am 31 Aug. 2011
Bearbeitet: Adam am 12 Dez. 2018
Do you mean something like this:
function GetSize(this)
props = properties(this);
totSize = 0;
for ii=1:length(props)
currentProperty = getfield(this, char(props(ii)));
s = whos('currentProperty');
totSize = totSize + s.bytes;
end
fprintf(1, '%d bytes\n', totSize);
end
  4 Kommentare
Dmitry Borovoy
Dmitry Borovoy am 1 Sep. 2011
well I tested it on public protected and private properties. It seems like all work properly
Lucas García
Lucas García am 1 Sep. 2011
Nicely done!

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (7)

Lucas García
Lucas García am 31 Aug. 2011
Unfortunately, there is no way to check the amount of memory that is being occupied by class objects, since MATLAB is storing references to C++ objects. As you say, whos is representing the size of the pointer to the created object, which will be 60 bytes (in 32-bit) or 112 bytes (in 64-bit).
However, you can create a function in your class and calculate the real memory of the object by manually querying for the memory of each of the properties in the class, like you do with whos for a matrix.
  2 Kommentare
Lucas García
Lucas García am 31 Aug. 2011
Also, if you are able to have the same elements of the object in one of the classic MATLAB data types, you will have a pretty good "estimate" of the amount of memory that your object takes:
>> warning off 'MATLAB:structOnObject'
>> s = builtin('struct', obj);
>> w = whos('s');
>> memObj = w.bytes
>> warning on 'MATLAB:structOnObject'
Andrew Janke
Andrew Janke am 5 Mär. 2019
Bearbeitet: per isakson am 11 Mär. 2019
> Unfortunately, there is no way to check the amount of memory that is being occupied by class objects, since MATLAB is storing references to C++ objects.
I'm confused by this: aren't Matlab user-defined objects (things defined with a classdef or an old-style @myclass directory) essentially structs with special behaviors? Their properties all contain Matlab arrays, just like struct fields, not C++ objects. (Except in Matlab's internals, but seems true for structs and cells as well, so I don't see why objects are special.) Why couldn't the default behavior of whos' size-counting be the equivalent of doing sizeof(builtin('struct', obj)) on objects?
This behavior seems to have changed as of some version before R2018b, too. When I create a classdef object, whos reports what looks to be the total size of the primitive Matlab arrays in its object graph, which is what I would expect if whos was now doing the equivalent of builtin('struct', obj) on objects.
classdef MyClass
properties
a
b
end
methods
function this = MyClass(a, b)
this.a = a;
this.b = b;
end
end
end
>> version
ans =
'9.5.0.944444 (R2018b)'
>> m = MyClass(zeros(1, 10^6), ones(1, 10^6));
>> whos
Name Size Bytes Class Attributes
ans 1x21 42 char
m 1x1 16000000 MyClass

Melden Sie sich an, um zu kommentieren.


Rick van Bijnen
Rick van Bijnen am 23 Mai 2019
Bearbeitet: Rick van Bijnen am 23 Mai 2019
I extended the code of Dmitry and Mario, such that it now also treats nested objects properly, and it pretty-prints the result. You can also put a size treshold, to only show significantly large fields.
Example output:
>> getMemSize(GPS, 1024^2, 'GPS')
[GPS]
usedgridpoints : 3 Mb
phi : 24 Mb
Vtrapx : 24 Mb
Vtrapy : 24 Mb
Vtrapz : 24 Mb
FLaplacian : 24 Mb
FUdd : 24 Mb
FFTshift_rphase : 24 Mb
FFTshift_kphase : 24 Mb
[BdGbasis3Dsymm]
BasisStates : 8 Gb [!]
PhiBuffer : 24 Mb
L : 76 Mb
SourceIndices : 16 Mb
TargetIndices : 16 Mb
TOTAL : 9 Gb [!]
Code:
function [ bytes ] = getMemSize( variable, sizelimit, name, indent )
if nargin < 2
sizelimit = -1;
end
if nargin < 3
name = 'variable';
end
if nargin < 4
indent = '';
end
strsize = 30;
props = properties(variable);
if size(props, 1) < 1
bytes = whos(varname(variable));
bytes = bytes.bytes;
if bytes > sizelimit
if bytes < 1024
fprintf('%s%s: %i\n', indent, pad(name, strsize - length(indent)), bytes);
elseif bytes < 2^20
fprintf('%s%s: %i Kb\n', indent, pad(name, strsize - length(indent)), round(bytes / 2^10));
elseif bytes < 2^30
fprintf('%s%s: %i Mb\n', indent, pad(name, strsize - length(indent)), round(bytes / 2^20));
else
fprintf('%s%s: %i Gb [!]\n', indent, pad(name, strsize - length(indent)), round(bytes / 2^30));
end
end
else
fprintf('\n%s[%s] \n\n', indent, name);
bytes = 0;
for ii=1:length(props)
currentProperty = getfield(variable, char(props(ii)));
pp = props(ii);
bytes = bytes + getMemSize(currentProperty, sizelimit, pp{1}, [indent, ' ']);
end
if length(indent) == 0
fprintf('\n');
name = 'TOTAL';
if bytes < 1024
fprintf('%s%s: %i\n', indent, pad(name, strsize - length(indent)), bytes);
elseif bytes < 2^20
fprintf('%s%s: %i Kb\n', indent, pad(name, strsize - length(indent)), round(bytes / 2^10));
elseif bytes < 2^30
fprintf('%s%s: %i Mb\n', indent, pad(name, strsize - length(indent)), round(bytes / 2^20));
else
fprintf('%s%s: %i Gb [!]\n', indent, pad(name, strsize - length(indent)), round(bytes / 2^30));
end
end
end
end

Mario Reutter
Mario Reutter am 13 Dez. 2017
Bearbeitet: Mario Reutter am 13 Dez. 2017
I extended the answer of @Dmitry Borovoy such that the function works with variables, structs, and objects:
function [ bytes ] = getSize( variable )
props = properties(variable);
if size(props, 1) < 1, bytes = whos(varname(variable)); bytes = bytes.bytes;
else %code of Dmitry
bytes = 0;
for ii=1:length(props)
currentProperty = getfield(variable, char(props(ii)));
s = whos(varname(currentProperty));
bytes = bytes + s.bytes;
end
end
end
We also need this helper function to achieve clean code. If you don't like it, you can just replace "varname(" and the following ")" with an apostrophe: ' .
function [ name ] = varname( ~ )
name = inputname(1);
end

Todd Fallesen
Todd Fallesen am 11 Feb. 2020
size_var = getVarSize(variable)
function size_var = getVarSize(var)
name = getVarName(var);
size = whos(name);
size_var = size.bytes;
end
function out = getVarName(var)
out = inputname(1);
end

SK
SK am 10 Jun. 2020
Bearbeitet: SK am 10 Jun. 2020
The problem with all the suggested solutions is that the matlab properties() function will not return the names of private properties. So while these suggested snippets of code will run to completion, the number they output at the end will not include the size of those private properties.
There appears to be no way to get the deep size of objects reliably other than converting the object recursively to a struct first (using struct()) and then using the code suggested by the posters above. Even if one used the meta class to get the private property names, getfield() will refuse to give the value of a private property and will throw an error.
One clunky solution would be to have a memsize function implemented inside every class. I don't see any other way. It's a mystery why Matlab doesn't provide such a function - something like memsize(classobj).
In addition, all the solutions above need to be modified to take into account (possibly nested) arrays of structs/objects and cell arrays.
  2 Kommentare
Steven Lord
Steven Lord am 10 Jun. 2020
Asking the question "How much memory does this variable use?" may seem simple, but it's not.
A = ones(10000);
B = A;
How much actual memory does B use? Is it around 10000*10000*8 (8 bytes/element for real full double)? Maybe not.
A(1) = 2;
How much actual memory does B use now?
Why exactly do you need to know how much memory the object uses? What would you do with this information? I can think of a couple potential answers to those questions, but I'm curious what your specific use case is.
Carsten Ridder
Carsten Ridder am 8 Okt. 2020
"Why exactly do you need to know how much memory the object uses? What would you do with this information?"
In order to choose between two different solutions to the same coding problem, the memore requirements is one of the things to consider.
I have to choose one of these solutions - the data content is exactly identical:
1) an array of a userdefined class @measpoint (whos: 43416 bytes, SAVE to disk: 3.4 MB)
2) two MATLAB-tables (whos: 59359818 and 5949040 bytes, SAVE to disk: 873 KB and 196 KB)
Other things to consider is performance like speed and coding simplicity.
Any suggestions?

Melden Sie sich an, um zu kommentieren.


Matt Raum
Matt Raum am 4 Dez. 2020
I run into this issue when trying to determine the memory footprint of objects derived from the handle base class.
I usually use the approach shown in the objbytes2() function, below. It calls getByteStreamFromArray(). I love that function.
It returns a larger size than objbytes1(). I think this is because it accounts for structural metadata and also for any hidden properties.
% Byte counting functions
varbytes = @(x)getfield(whos('x'),'bytes');
objbytes1 = @(x)sum(cellfun(@(p)varbytes(x.(p)),properties(x)));
objbytes2 = @(x)numel(getByteStreamFromArray(x));
% Sample application
x = figure;
varbytes(x)
objbytes1(x)
objbytes2(x)

Ivan Garcia
Ivan Garcia am 3 Jan. 2023
Bearbeitet: Ivan Garcia am 3 Jan. 2023
A quick way of doing this is saving the var in a mat file. This is if you want a ballpark idea if the object is lightweight or not. This should not be used for a precise variable size measurement.
save('var1.mat', 'var1');
Then check the file size in the OS, e.g.,:
>> !ls -alg
total 2699
drwxr-xr-x 2 users 4 Jan 3 14:47 .
drwxr-xr-x 12 users 12 Jan 3 14:42 ..
-rw-r--r-- 1 users 1358542 Jan 3 13:29 var1.mat
  2 Kommentare
Andrew Janke
Andrew Janke am 3 Jan. 2023
I'm not sure I'd recommend that. There's overhead in the MAT-file structure itself, or in some cases it may be using duplication/de-duplication or data compression, and some Matlab data structures (e.g. especially cellstrs and maybe strings) have significantly different MAT-file representations. The size of a MAT-file serialization of a Matlab value/array can vary a lot from its in-memory representation.
Ivan Garcia
Ivan Garcia am 3 Jan. 2023
At least for my case, I needed to know if an object was lightweight or not. And the above answered the question (I got 1 MB from the variable). I clarified that other approaches should be used for precise measurement. Thanks

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Construct and Work with Object Arrays finden Sie in Help Center und File Exchange

Produkte

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by