수색…
비고
관리되는 .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를 적절히 구성하는 방법을 보여줍니다. 이런 방식으로 메모리를 할당하는 것은 매우 고안된 것이며 무의미한 일입니다.