【问题标题】:How can I tell how much memory a handle object uses in matlab如何判断一个句柄对象在matlab中使用了多少内存
【发布时间】:2011-01-24 05:01:34
【问题描述】:

如果我声明一个对象是句柄的子类 类定义 obj

例如,假设我有一个带有字段 bar 的类 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 指向的总内存量?

【问题讨论】:

    标签: matlab class object handle matlab-class


    【解决方案1】:

    作为 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 语言中,使用指向任意内存块的指针。

    【讨论】:

    • 谢谢!这真是一个很好的建议。一个问题,因为我不明白 matlab 如何决定分配新内存和复制:将 foo 转换为 struct 会占用多少内存?换句话说,如果 foo 有一个 1 GB 的字段,将其转换为结构会导致 MATLAB 消耗额外的 GB 内存吗?
    • 如何估计 Java 对象的大小? - 这些在 Matlab 中报告为 0 字节...
    • @Marc:将 foo 转换为 struct 不会占用太多内存。只是结构本身被转换。结构字段的内容,包括假设的 1 GB 字段,将使用 matlab 的写时复制优化共享。
    • @Yair Altman:您需要调用 Java 代码来估计 Java 对象的大小,当 isjava() 表示您正在查看 Java 对象时,从 Matlab 代码中调用它。没有标准的 Java SDK 调用来做这个 AFAIK。我使用了 JavaWorld 的 "sizeof for Java" 库 (javaworld.com/javaworld/javaqa/2003-12/…),并在其上添加了一个小 M 代码包装器。新的 1.6 JVM 可能有更好的工具供您使用,可能是通过从 JVM 中调用分析挂钩。
    【解决方案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.
    

    【讨论】:

    • 我认为这不适用于递归或嵌套句柄,但这是一个不错的建议
    猜你喜欢
    • 2018-03-07
    • 2010-09-19
    • 1970-01-01
    • 2023-04-07
    • 2011-04-20
    • 2012-12-03
    • 1970-01-01
    • 2011-11-18
    相关资源
    最近更新 更多