matlab中如何知道句柄对象使用了多少内存

发布于 2024-08-23 18:41:32 字数 481 浏览 10 评论 0原文

如果我声明一个对象是句柄的子类 类定义 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 指向的总内存?

If I declare an object to be a subclass of handle
classdef obj < handle
my object is now essentially a "pointer" to some memory somewhere. How do I find out how much memory my object is using up?

For example, say I have a class foo with a field bar

classdef foo < handle 
properties
    bar = randn(1000);
end

bar takes up 8 megabytes (8 bytes * 1 million numbers)

but if I type

obj = foo();
whos('obj');

I get

Name      Size            Bytes  Class    Attributes

  obj      1x1                60  foo                

How do I find out how much total memory obj points to?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

天冷不及心凉 2024-08-30 18:41:32

作为一种破解,将其转换为结构并查看占用多少空间。我认为这将公开“常规”对象字段中的所有数据。

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 代码级别存在别名甚至循环引用,因此在递归时需要注意这一点。 (抱歉,我不知道如何在新的面向对象系统中处理这个问题。)

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() 不会让您区分这些情况。处理这个问题很困难;据我所知,执行此操作的唯一方法是使用 MEX 文件获取 mxarray 的数据指针并自行遍历对象树,检测别名指针并计算别名字节。

当对象的组件可以共享时,这是测量内存中对象的大小的一个普遍问题。它们不是离散的物理对象。至少你不是在 C 语言中使用指向任意内存块的指针。

As a hack, convert it to a struct and see how much space that takes up. I think that will expose all the data in "regular" object fields.

f = foo();
origWarn = warning();
warning off 'MATLAB:structOnObject'
s = builtin('struct', f); % use 'builtin' in case @foo overrides struct()
warning(origWarn);

Then you can see it in whos.

>> whos
  Name      Size              Bytes  Class     Attributes

  f         1x1                  60  foo                 
  s         1x1             8000124  struct       

This is just a first order approximation. It will tell you how much memory its fields are using. If any of them contain handle objects, you need to recurse down the fields of that struct and convert any other handle objects to struct to count their fields. (If you want to include Java objects' memory, you'll also need a separate function to estimate their storage size. Probably not worth the bother.) Now that Matlab has closures, function handles may also contain data; you'll need to punch in to those using functions() if you want to count closed-over data.

If you're working with handle objects, you may have aliasing and even circular references at the M-code level, so you'd need to watch out for that when recursing. (Sorry, I don't know how to handle that in the new OO system.)

The memory display in whos will also double-count arrays that are sharing memory via Matlab's copy-on-write optimization. Here's a concrete example.

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              

In reality, s is only consuming about 80K; it just contains three pointers to x. And that 80K is the same 80K that x itself is consuming. Unless you modify any of them; then a new array is allocated. Whos() won't let you differentiate those cases. Handling this is hard; AFAIK the only way to do this is to use a MEX file to get the mxarray's data pointer(s) and walk the object tree yourself, detecting aliased pointers and counting the aliased bytes.

This is a general problem with measuring the size of objects in memory when their components could be shared. They're not discrete physical objects. At least you're not in C, working with pointers to arbitrary memory blocks.

给妤﹃绝世温柔 2024-08-30 18:41:32

我刚刚发现的一个简单方法是 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.

An easy way I just found is what Dmitry Borovoy suggests here. I wanted to make it available here.

Derive your class from a base class which provides a method, that collects data from all its properties. Code take from given link above.

    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

Sample usage:

>> fprintf('%.1f MB in use.\n',do.sde.get_mem/1024^2)
7413.0 MB in use.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文