如果我声明一个对象是句柄的子类 classdef obj<处理 我的对象现在基本上是某个内存的“指针”。如何找出对象耗尽的内存量?
例如,假设我有一个带字段栏的类foo
classdef foo < handle
properties
bar = randn(1000);
end
bar占用8兆字节(8字节* 100万个数字)
但如果我输入
obj = foo();
whos('obj');
我得到了
Name Size Bytes Class Attributes
obj 1x1 60 foo
如何找出obj指向的总内存量?
答案 0 :(得分:11)
作为一个黑客,将其转换为结构,并查看占用多少空间。我认为这将公开“常规”对象字段中的所有数据。
f = foo();
origWarn = warning();
warning off 'MATLAB:structOnObject'
s = builtin('struct', f); % use 'builtin' in case @foo overrides struct()
warning(origWarn);
然后你可以看到它。
>> whos
Name Size Bytes Class Attributes
f 1x1 60 foo
s 1x1 8000124 struct
这只是一阶近似。它会告诉你它的字段使用了多少内存。如果它们中的任何一个包含句柄对象,则需要递归该结构的字段并将任何其他句柄对象转换为struct以计算其字段。 (如果你想包含Java对象的内存,你还需要一个单独的函数来估计它们的存储大小。可能不值得麻烦。)现在Matlab有闭包,函数句柄也可能包含数据;如果你想计算封闭数据,你需要使用函数()打卡。
如果你正在使用句柄对象,你可能在M代码级别有别名甚至循环引用,所以你需要在递归时注意它。 (对不起,我不知道如何在新的OO系统中处理它。)
其中的内存显示也将通过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中,使用指向任意内存块的指针。
答案 1 :(得分: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.