FreeHGlobal を呼び出す関数の最後に、頻繁に使用する関数 (おそらく毎秒 30 回) で AllocHGlobal (常に同じサイズ) を使用する状況があります。
AllocHGlobal で割り当てられたメモリの一部を保持し、クラス Dispose のときにそれを解放する方が良いですか、それとも関数を呼び出すたびに割り当て/解放する必要がありますか?
このメモリが C# でどのように動作するかはわかりません。これは私にとって「新しい世界」です。
FreeHGlobal を呼び出す関数の最後に、頻繁に使用する関数 (おそらく毎秒 30 回) で AllocHGlobal (常に同じサイズ) を使用する状況があります。
AllocHGlobal で割り当てられたメモリの一部を保持し、クラス Dispose のときにそれを解放する方が良いですか、それとも関数を呼び出すたびに割り当て/解放する必要がありますか?
このメモリが C# でどのように動作するかはわかりません。これは私にとって「新しい世界」です。
30秒は永遠です。FreeHGlobal を finally ブロックに配置して、確実に解放する方がはるかに簡単です。ファイナライザーと IDisposable の歌と踊りを行う必要がなくなります。さて、クライアントのコード。
ヒープ チャーンよりもキャッシングを優先しても、ミリ秒の範囲になるまで効果はありません。
他のパフォーマンスの質問と同様に、最初にクリーンなコードを記述し、必要なものを測定して最適化します。
オブジェクトが複数のスレッドで使用されないことがかなり確実な場合(したがって、問題の関数を同時に呼び出す)、割り当てられたメモリをキャッシュすることは問題ないようです。
ガベージコレクションに依存して管理されていないメモリブロックをキャッシュすることにした場合、リクレイはメモリを十分に早く解放するのに十分ではありません。管理されていないメモリ(AllocHGlobal)は、CLRで割り当てられたメモリに対してカウントされないため、オブジェクトのガベージコレクションが遅延する可能性があります)。オブジェクトにIDisposableを実装し、適切に使用する必要があります。
次の場合に限り、これを行うことができます。
IDisposable
あり、Dispose()
メソッドはメモリを解放する必要があります。もちろん、クラス コンシューマはブロックを呼び出すDispose()
か使用する必要がありusing(){}
ます。)ただし、P/Invoke 呼び出しの実際のマーシャリングがボトルネックになる可能性が高くなります。コードを実際にプロファイリングしましたか、それともマイクロ最適化を行っていますか?