Как я могу сказать, сколько памяти объект дескриптора использует в Matlab - PullRequest
15 голосов
/ 05 марта 2010

Если я объявляю объект подклассом дескриптора 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                

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

Ответы [ 2 ]

11 голосов
/ 05 марта 2010

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

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       

Это только первое приближение. Он скажет вам, сколько памяти используют его поля. Если какой-либо из них содержит объекты-дескрипторы, вам нужно найти поля этой структуры и преобразовать любые другие объекты-дескрипторы в структуру для подсчета их полей. (Если вы хотите включить память объектов Java, вам также понадобится отдельная функция для оценки размера их хранилища. Вероятно, не стоит беспокоиться.) Теперь, когда в Matlab есть замыкания, дескрипторы функций также могут содержать данные; вам нужно будет ввести тех, кто использует функции (), если вы хотите считать закрытые данные.

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

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

2 голосов
/ 03 марта 2015

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

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

    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.
...