1

FreeHGlobal を呼び出す関数の最後に、頻繁に使用する関数 (おそらく毎秒 30 回) で AllocHGlobal (常に同じサイズ) を使用する状況があります。

AllocHGlobal で割り当てられたメモリの一部を保持し、クラス Dispose のときにそれを解放する方が良いですか、それとも関数を呼び出すたびに割り当て/解放する必要がありますか?

このメモリが C# でどのように動作するかはわかりません。これは私にとって「新しい世界」です。

4

3 に答える 3

2

30秒は永遠です。FreeHGlobal を finally ブロックに配置して、確実に解放する方がはるかに簡単です。ファイナライザーと IDisposable の歌と踊りを行う必要がなくなります。さて、クライアントのコード。

ヒープ チャーンよりもキャッシングを優先しても、ミリ秒の範囲になるまで効果はありません。

于 2011-01-04T23:34:53.187 に答える
1

他のパフォーマンスの質問と同様に、最初にクリーンなコードを記述し、必要なものを測定して最適化します。

オブジェクトが複数のスレッドで使用されないことがかなり確実な場合(したがって、問題の関数を同時に呼び出す)、割り当てられたメモリをキャッシュすることは問題ないようです。

ガベージコレクションに依存して管理されていないメモリブロックをキャッシュすることにした場合、リクレイはメモリを十分に早く解放するのに十分ではありません。管理されていないメモリ(AllocHGlobal)は、CLRで割り当てられたメモリに対してカウントされないため、オブジェクトのガベージコレクションが遅延する可能性があります)。オブジェクトにIDisposableを実装し、適切に使用する必要があります。

于 2011-01-04T23:40:25.827 に答える
0

次の場合に限り、これを行うことができます。

  • 必要なメモリの量は、常に割り当てのサイズ以下です。(あなたはすでにこれが事実であることを示しました。)
  • メソッドは、一度に複数のスレッドから呼び出されません。
  • メソッドは再入可能ではありません。
  • メモリが不要になったら、慎重にメモリを解放してください。(つまり、ポインタが非静的クラス フィールドに保存されている場合、クラスは実装する必要がIDisposableあり、Dispose()メソッドはメモリを解放する必要があります。もちろん、クラス コンシューマはブロックを呼び出すDispose()か使用する必要がありusing(){}ます。)

ただし、P/Invoke 呼び出しの実際のマーシャリングがボトルネックになる可能性が高くなります。コードを実際にプロファイリングしましたか、それともマイクロ最適化を行っていますか?

于 2011-01-04T23:34:22.270 に答える