3

私のMEXファイルはC++/ CLIで記述されており、C#で記述されたDLLを呼び出します。

オブジェクトをgcnewする場合、mexFunctionが戻ったときにガベージコレクションを行うべきではありませんか?その参照は失われるはずですが、ガベージコレクションは行われていないようです... mex関数を呼び出すたびに、MATLABのメモリ割り当てが増加します(いいえ、メモリはMATLAB変数に使用されません)。

狭いスコープで大きなダミー値を作成してみましたが、MEXファイルをステップ実行すると、割り当てられて解放されたメモリを確認できます。しかし、mexFunction =(で作成されたメインオブジェクトではそうではありません

デストラクタとファイナライザで削除しようとしましたが、ガベージコレクトに取得できません。MATLABに戻るときに、管理対象メモリを解放するにはどうすればよいですか?

外部DLLファイラーは問題ではないと思います。説明のために、私はこのばかげたmexFunctionを作成しました:

public ref class Foo
{
    public:
        Foo()
        {
            Dictionary<int,String^>^ bar = gcnew Dictionary<int,String^>;
            for(int i=0;i<10000000;i++)
            {
                bar->Add(i, "abcdefghijklmnopqrstuvxyz");
            }
        }
};

void mexFunction(int nlhs, mxArray* plhs[], int nrhs, mxArray* prhs[])
{
    Foo^ test = gcnew Foo();
}

これにより、MATLABのメモリが約300 MB増加しますが、その後の呼び出しでは、実際のMEXファイルのようにメモリがさらに増えることはありません。

編集:

私は自分の質問に答えました、犯人はmxArrayToStringでした

4

2 に答える 2

2

私は問題を見つけました、結局それは.net関連ではなかったことがわかりました...その赤いニシンでごめんなさい

new、malloc、またはmxMallocを使用していなかったため、管理されていないすべてのメモリがスタックにあり、mexFunctionが終了したときにクリーンアップされると誤って想定していました。

ただし、mxArrayToStringは、mxGetDataや他のmx *関数のように、MATLABデータへのポインターを返しません。データをヒープにコピーし、mxFreeを呼び出して解放する必要があります。System :: String ^を作成するための入力としてmxArrayToStringを使用しました。必要な変更は、temporay charポインターを保存し、それをString ^コンストラクターに使用してから、mxFreeにすることだけでした。

もう一度SEOの場合:mxArrayToStringからのポインターはmxFreeする必要があります

于 2012-09-26T09:09:10.550 に答える
2

ガベージコレクションは、メモリを.NETヒープ内で使用可能としてマークします。.NETヒープを縮小しません(これにより、メモリが他のプロセスで使用可能になり、アドレス空間がプロセス内の非.NETコードで使用可能になります)。

ラージオブジェクトヒープが縮小されることはなく、1,000万エントリのディクショナリはおそらくLOHに入るのに十分な大きさであることが明示的に文書化されています。

于 2012-09-19T20:14:03.600 に答える