Как узнать, сколько памяти использует объект handle в matlab

Если я объявляю объект подклассом дескриптора classdef obj < ручка мой объект теперь по существу является "указателем" на какую-то память. Как узнать, сколько памяти использует мой объект?

Например, скажем, у меня есть класс foo с панелью полей

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

бар занимает 8 мегабайт (8 байт * 1 миллион номеров)

но если я напечатаю

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

Я получаю

Name      Size            Bytes  Class    Attributes

  obj      1x1                60  foo                

Как узнать, сколько очков суммарной памяти указывает?

Ответы

Ответ 1

Как взломать, преобразуйте его в структуру и посмотрите, сколько места занимает занятие. Я думаю, что все данные будут отображаться в "обычных" объектных полях.

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 имеет замыкания, дескрипторы функций также могут содержать данные; вам нужно будет использовать функции(), если вы хотите считать закрытые данные.

Если вы работаете с объектами handle, у вас могут быть псевдонимы и даже круговые ссылки на уровне 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 - это тот же самый 80K, что и сам x потребляет. Если вы не модифицируете ни одно из них; то выделяется новый массив. Whos() не позволит вам дифференцировать эти случаи. Обработка этого затруднена; AFAIK единственный способ сделать это - использовать MEX файл для получения указателя (ов) данных mxarray и самостоятельно пройти дерево объектов, обнаруживать сглаженные указатели и подсчитывать псевдонимы.

Это общая проблема с измерением размера объектов в памяти, когда их компоненты могут совместно использоваться. Они не являются дискретными физическими объектами. По крайней мере, вы не на C, работая с указателями на произвольные блоки памяти.

Ответ 2

Я просто нашел, что Дмитрий Боровой предлагает здесь. Я хотел сделать его доступным здесь.

Вывести свой класс из базового класса, который предоставляет метод, который собирает данные из всех его свойств. Код берется из указанной ссылки выше.

    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.