15

オブジェクトを handle classdef obj < handle のサブクラスとして宣言すると、オブジェクトは本質的にどこかのメモリへの「ポインタ」になります。オブジェクトが使用しているメモリの量を確認するにはどうすればよいですか?

たとえば、フィールドバーを持つクラス 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

ハックとして、それを構造体に変換し、どれだけのスペースを占めるかを確認してください。「通常の」オブジェクトフィールドのすべてのデータが公開されると思います。

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 への 3 つのポインターが含まれているだけです。そして、その 80K は、x 自体が消費している 80K と同じです。それらのいずれかを変更しない限り。次に、新しい配列が割り当てられます。Whos() では、これらのケースを区別できません。これを処理するのは難しいです。私の知る限り、これを行う唯一の方法は、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 に答える