web-dev-qa-db-ja.com

MATLABのガベージコレクター?

それのあなたのメンタルモデルは何ですか?それはどのように実装されていますか?どの長所と短所がありますか? MATLABGCとPython GC

他の点では無害に見えるコードでMATLABネスト関数を使用すると、奇妙なパフォーマンスのボトルネックが発生することがあります。これはGCが原因であると確信しています。ガベージコレクターはVM)の重要な部分であり、Mathworksはそれを公開しません。

私の質問はMATLAB自身についてです ヒープ とGC! Java/COMオブジェクトの処理/「メモリ不足」エラーの防止/スタック変数の割り当てについてではありません。

EDIT:最初の応答は、実際には「なぜ気にする必要があるのか​​」というメタ回答です。 リンクリスト または [〜#〜] mvc [〜#〜] パターンを実装するとGCが現れるので、私は気にします。

28
Mikhail

これは私が集めた事実のリストです。 GCの代わりに、メモリ(デ)割り当てという用語がこのコンテキストでより適切であるように思われます。

私の主な情報源は、Lorenのブログ(特にそのコメント)とMATLAB Digestの this 記事です。

可能性のある大きなデータセットを使用した数値計算の方向性のため、MATLABは スタックオブジェクト パフォーマンスの最適化に非常に優れています データのインプレース演算 および call-by-reference 関数の引数。また、その方向性のために、そのメモリモデルは基本的に 異なる JavaのようなOO言語とは異なります。

MATLABには、バージョン7まで公式にユーザー定義のヒープメモリがありませんでした(バージョン6では、schema.mファイルに文書化されていないreference機能がありました)。 MATLAB 7には、 ネストされた関数(クロージャ)とハンドルオブジェクト の両方の形式のヒープがあり、それらの実装は同じ基盤を共有しています。補足として、OOは エミュレート である可能性があります(2008aより前の興味深い)。

驚くべきことに、関数ハンドル(クロージャ)によってキャプチャされた囲んでいる関数のワークスペース全体を調べることができます。MATLABヘルプの関数 functions(fhandle) を参照してください。これは、囲んでいるワークスペースがメモリ内で凍結されていることを意味します。これが、ネストされた関数内でcellfun/arrayfunを使用すると非常に遅くなることがある理由です。

Loren および Brad Phelan によるオブジェクトのクリーンアップに関する興味深い投稿もあります。

MATLABでのヒープの割り当て解除に関する最も興味深い事実は、私の意見では、MATLABは、スタックが割り当て解除されるたびに、つまりすべての関数を離れるときにそれを実行しようとすることです。これには 利点 がありますが、ヒープの割り当て解除が遅い場合は、CPUのペナルティも大きくなります。また、MATLABでは、実際には非常に遅いシナリオもあります。

コードに影響を与える可能性のあるMATLABメモリの割り当て解除のパフォーマンスの問題はかなり悪いです。コードの実行速度が突然20倍遅くなり、関数を終了してから呼び出し元に戻るまでに数秒かかる場合がある場合(クリーンアップに費やした時間)、意図せずに循環参照をコードに導入していることに常に気付きます。これは既知の問題です。 Dave Foti および この古いフォーラム投稿 この画像の視覚化パフォーマンスを作成するために使用されるコードを参照してください(テストは異なるマシンで行われるため、絶対的なタイミング比較異なるMATLABバージョンの意味はありません):

参照オブジェクトのプールサイズの線形増加は、MATLABパフォーマンスの多項式(または指数)減少を意味します!値オブジェクトの場合、パフォーマンスは予想どおり線形です。

これらの事実を考慮すると、MATLABはヒープの割り当て解除にまだあまり効率的な形式の参照カウントを使用していないと推測できます。

[〜#〜] edit [〜#〜]多くの小さいで常にパフォーマンスの問題が発生しましたネストされた関数ですが、最近、少なくとも2006aでは、数メガバイトのデータを含む単一のネストされたスコープのクリーンアップもひどいことに気付きました。ネストされたスコープ変数をに設定するだけで1.5秒かかります。空の!

編集2:ついに答えが得られました- Dave Foti自身による 。彼は欠陥を認めていますが、MATLABは現在の決定論的クリーンアップアプローチを維持すると述べています。

凡例:実行時間は短い方が良い

R2006aR2008aR2009a

44
Mikhail

MATLABは、ワークスペースブラウザーまたは「whos」コマンドを使用してワークスペースを非常に明確にします。これにより、コマンドによって作成されたすべてのオブジェクトと、それらが使用するメモリの量が表示されます。

feature('memstats')

mATLABで使用可能なメモリの最大の連続ブロックが表示されます。これは、作成できる最大の行列であることを意味します。 「clear」コマンドを使用すると、これらのオブジェクトがメモリから同期的に削除され、スペースが解放されて再度使用できるようになります。

JVMは、Javaアイテムのガベージコレクションのみを処理します。したがって、エディターでファイルを開いて閉じると、Javaがウィンドウの削除を処理し、メモリからテキストなど。MATLABワークスペースでJavaオブジェクトを作成する場合、最初にクリアする必要があり、次にjvmでクリーンアップできます。

テクニカルノートには、プログラムメモリの管理に関する多くの情報があります: http://www.mathworks.com/support/tech-notes/1100/1106.html

そして私は最近、MATLABデスクトップブログでJavaメモリの処理について書きました: http://blogs.mathworks.com/desktop/2009/08/17/calling-Java-from -matlab-memory-issues /

関数が終了したとき、または変数のサイズを変更したときに割り当てられたメモリがどうなるかについて学術的に興味がある場合は、それが企業秘密であり、リリースごとに変更されると確信しています。決して気付かないはずです。オブジェクトmanagmenetに関連していると思われるパフォーマンスの問題が発生した場合は、テクニカルサポートにヘルプチケットを提出してください。 http://www.mathworks.com/support

13
Mike Katz

ある種のPython vsMATLAB引数を作成しようとしているようです。私はその引数にはそれほど興味がありません。

あなたのメタ質問に対するメタ回答。

あなたが気にしないことは実際にはかなり重要です。私がそう言うとき、私はそれをMATLABメモリ管理に限定するつもりはありません。これは、Python、Java、.NET、および動的メモリ割り当てを行い、現在も活発に開発されているその他の言語にまで及びます。

メモリ管理の現在のメカニズムについてよく知っているほど、その特定の実装に対して防御的にコーディングする可能性が高くなり、将来のパフォーマンスの向上によるメリットが得られなくなる可能性が高くなります。これの多くの良い例は、developerworks.comでBrianGoetzによって作成されたJavaのgcにあります。

http://www.ibm.com/developerworks/library/j-jtp01274.html

あなたは知ることが重要であると言うことができます。私はそれがすべて要件についてであると反論します。より適切な質問は、プロジェクトで検討している言語が、パフォーマンス、開発努力、保守性、移植性、開発者の専門知識などの点で私のニーズを満たしているかどうかです。

参照カウントよりもマークスイープよりも世代別のgcを使用する必要があるプロジェクトを見たことがありません。すぐに見られるとは思いません。

2
Todd