수색…


비고

관리되는 .NET 응용 프로그램의 성능이 중요한 응용 프로그램은 GC에 심각한 영향을받을 수 있습니다. GC가 실행되면 다른 모든 스레드는 완료 될 때까지 일시 중단됩니다. 이러한 이유로 GC 프로세스를주의 깊게 평가하고 실행 시간을 최소화하는 방법을 결정하는 것이 좋습니다.

관리되지 않는 리소스

GC와 "heap"에 대해 이야기 할 때 우리는 관리되는 힙 (heap) 이라고 불리는 것을 실제로 말하고 있습니다. 관리 힙의 오브젝트는 관리 힙에 없는 자원에 액세스 할 수 있습니다 (예 : 파일에 쓰거나 파일에서 읽을 때). 파일을 열어서 읽은 다음 예외가 발생하여 파일 핸들이 정상적으로 닫히지 않을 때 예기치 않은 동작이 발생할 수 있습니다. 이러한 이유로 .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 구현이 사용 가능한 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 로 관리되는 리소스를 보호하고 Finalizer를 적절히 구성하는 방법을 보여줍니다. 이런 방식으로 메모리를 할당하는 것은 매우 고안된 것이며 무의미한 일입니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow