15

如果我将一个对象声明为句柄 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 指向的总内存量?

4

2 回答 2

11

作为 hack,将其转换为 struct 并查看占用了多少空间。我认为这将在“常规”对象字段中公开所有数据。

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 有闭包,函数句柄也可能包含数据;如果要计算封闭数据,则需要使用 functions() 打孔。

如果您使用句柄对象,您可能在 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 语言中,使用指向任意内存块的指针。

于 2010-03-05T18:38:42.247 回答
3

我刚刚发现的一个简单方法是Dmitry Borovoy在这里提出的建议。我想让它在这里可用。

从提供方法的基类派生您的类,该方法从其所有属性中收集数据。代码取自上面给定的链接。

    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.
于 2015-03-03T09:40:14.830 回答