サーチ…


備考

管理対象.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で管理対象リソースを保護する方法を示すためのものです。この方法でメモリのチャンクを割り当てることは非常に工夫されており、無意味である可能性があります。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow