MATLAB Answers

How to get size of an object

1.477 views (last 30 days)
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?

  0 Comments

Sign in to comment.

Accepted Answer

Dmitry Borovoy
Dmitry Borovoy on 31 Aug 2011
Edited: Adam on 12 Dec 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 Comments

Show 1 older comment
Lucas García
Lucas García on 1 Sep 2011
That certainly does work as long as your properties GetAccess method is set to public.
Dmitry Borovoy
Dmitry Borovoy on 1 Sep 2011
well I tested it on public protected and private properties. It seems like all work properly

Sign in to comment.

More Answers (6)

Lucas García
Lucas García on 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 Comments

Lucas García
Lucas García on 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 on 5 Mar 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

Sign in to comment.


Rick van Bijnen
Rick van Bijnen on 23 May 2019
Edited: Rick van Bijnen on 23 May 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

  0 Comments

Sign in to comment.


Mario Reutter
Mario Reutter on 13 Dec 2017
Edited: Mario Reutter on 13 Dec 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

  0 Comments

Sign in to comment.


Todd Fallesen
Todd Fallesen on 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

  0 Comments

Sign in to comment.


SK
SK on 10 Jun 2020
Edited: SK on 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 Comments

Steven Lord
Steven Lord on 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 on 8 Oct 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?

Sign in to comment.


Matt Raum
Matt Raum on 4 Dec 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)

  0 Comments

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!

Translated by