サーチ…
備考
管理対象.NETアプリケーションのパフォーマンス重視アプリケーションは、GCによって深刻な影響を受ける可能性があります。 GCが実行されると、他のすべてのスレッドは完了するまで中断されます。このため、GCプロセスを慎重に評価し、実行するタイミングを最小限に抑える方法を決定することをお勧めします。
管理されていないリソース
GCと「ヒープ」について言及すると、実際にはマネージヒープと呼ばれるものについて話しています 。 管理されたヒープ上のオブジェクトは、ファイルへの書き込みやファイルからの読み込みなど、管理されたヒープ上にないリソースにアクセスできます。予期しない動作は、ファイルが読み取りのために開かれた後に例外が発生し、ファイルハンドルが通常どおりに閉じるのを防ぐ場合に発生する可能性があります。このため、.NETでは管理されていないリソースでIDisposable
インターフェイスが実装されている必要があります。このインタフェースには、パラメータなしのDispose
という単一のメソッドがあります。
public interface IDisposable
{
Dispose();
}
管理されていないリソースを処理するときは、それらが適切に処理されていることを確認する必要があります。これは、 finally
ブロックまたはusing
ステートメントでDispose()
明示的に呼び出すことによって実行できます。
StreamReader sr;
string textFromFile;
string filename = "SomeFile.txt";
try
{
sr = new StreamReader(filename);
textFromFile = sr.ReadToEnd();
}
finally
{
if (sr != null) sr.Dispose();
}
または
string textFromFile;
string filename = "SomeFile.txt";
using (StreamReader sr = new Streamreader(filename))
{
textFromFile = sr.ReadToEnd();
}
後者が好ましい方法であり、コンパイル時に自動的に前者に展開されます。
管理されていないリソースをラップするときにSafeHandleを使用する
管理されていないリソースのラッパーを記述するときは、 IDisposable
とfinalizerを実装するのではなく、 SafeHandle
サブクラスSafeHandle
を行う必要があります。 SafeHandle
サブクラスは、ハンドルリークの可能性を最小限に抑えるため、できるだけ小さく、シンプルにする必要があります。これは、SafeHandleの実装が、使用可能なAPIを提供するためにそれをラップするクラスの内部実装の詳細である可能性が高いことを意味します。このクラスは、たとえプログラムがSafeHandle
インスタンスをリークしても、アンマネージハンドルが解放されることを保証します。
using System.Runtime.InteropServices;
class MyHandle : SafeHandle
{
public override bool IsInvalid => handle == IntPtr.Zero;
public MyHandle() : base(IntPtr.Zero, true)
{ }
public MyHandle(int length) : this()
{
SetHandle(Marshal.AllocHGlobal(length));
}
protected override bool ReleaseHandle()
{
Marshal.FreeHGlobal(handle);
return true;
}
}
免責事項:この例は、 IDisposable
を実装し、ファイナライザを適切に設定するSafeHandle
で管理対象リソースを保護する方法を示すためのものです。この方法でメモリのチャンクを割り当てることは非常に工夫されており、無意味である可能性があります。