제가 올바르게 이해했다면 .net 런타임은 항상 저를 따라 정리합니다. 따라서 새 객체를 생성하고 코드에서 참조를 중단하면 런타임이 해당 객체를 정리하고 해당 객체가 차지했던 메모리를 확보합니다.
그렇다면 왜 일부 객체에는 소멸자나 처분 메서드가 필요할까요? 더 이상 참조되지 않으면 런타임이 해당 객체를 정리하지 않나요?
파이널라이저는 파일 핸들, 소켓, 커널 객체 등과 같은 부족한 리소스를 시스템에 다시 릴리스하기 위해 필요합니다. 파이널라이저는 항상 오브젝트 수명이 끝날 때 실행되므로 핸들을 해제할 수 있는 지정된 장소입니다.
Dispose패턴은 리소스의 결정론적 소멸을 제공하는 데 사용됩니다. .net 런타임 가비지 수집기는 비결정적이기 때문에(즉, 런타임이 언제 오래된 개체를 수집하고 파이널라이저를 호출할지 확신할 수 없음) 시스템 리소스를 결정적으로 해제할 수 있는 방법이 필요했습니다. 따라서
Dispose` 패턴을 올바르게 구현하면 리소스를 결정적으로 해제하고 소비자가 부주의하여 객체를 폐기하지 않는 경우 파이널라이저가 객체를 정리합니다.
Dispose`가 필요한 이유에 대한 간단한 예로 퀵 앤 더티 로그 메서드를 들 수 있습니다:
public void Log(string line)
{
var sw = new StreamWriter(File.Open(
"LogFile.log", FileMode.OpenOrCreate, FileAccess.Write, FileShare.None));
sw.WriteLine(line);
// Since we don't close the stream the FileStream finalizer will do that for
// us but we don't know when that will be and until then the file is locked.
}
위의 예제에서 가비지 수집기가 StreamWriter
객체의 파이널라이저를 호출할 때까지 파일은 잠긴 상태로 유지됩니다. 그 동안 로그를 쓰기 위해 메서드를 다시 호출할 수 있지만 이번에는 파일이 여전히 잠겨 있기 때문에 실패할 수 있기 때문에 문제가 발생합니다.
올바른 방법은 객체 사용이 끝나면 객체를 폐기하는 것입니다:
public void Log(string line)
{
using (var sw = new StreamWriter(File.Open(
"LogFile.log", FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))) {
sw.WriteLine(line);
}
// Since we use the using block (which conveniently calls Dispose() for us)
// the file well be closed at this point.
}
참고로 기술적으로 파이널라이저와 소멸자는 같은 의미입니다. 저는 C# 소멸자를 &39;파이널라이저'라고 부르는 것을 선호하는데, 그렇지 않으면 C#과 달리 결정론적인 C++ 소멸자와 혼동하는 경향이 있기 때문입니다.
하지만 여기서 중요한 점 다시 한번 강조하십시오 이전 대답이 优秀 드리겠습니다. 특히 있는 횡격막탈장의
>. 만약 내가 제대로 파악 후 클린업합니다 닷넷 (.net) 기반 런타임용으로 개발하십시오 항상 나를.
이것은 단지 부분적으로 정확하다. 실제로 .NET 만 제공사항 자동일 특정 관리 리소스 : 메인 메모리. 필요한 모든 다른 리소스와의 수작업식 cleanup.<, sup>, 1) < /sup>;
특별한 자격을 얻을 수 있는 거의 모든 논의가 기묘하게 메인 메모리, 프로그램 '이다. # 39 의 메인 메모리는 물론 there& 좋은 이유는 - 사샤 크레스트 리소스에는 경우가 많다. 그러나 기억해야 할 것 이외에도 it& # 39 의 가치가 있는 가지유형의 에너지원도 관리할 필요가 있다.
이 시스템이 메모리 압력을 받지 않고 실행하십시오 쓰레기요 모음기 그칠 데 꼭 필요한 경우를 제외하고, 확보하십시오 일부 메모리. 즉, 이 때, 반드시 GC 를 실행할 수 없다.
데이터베이스 연결 틀렸다니까 이제 상상을 해 보세요. 넌 이제 경우 5월 이후 GC 클린업합니다 접속되어야 데이터베이스입니까 필요 이상으로 훨씬 더 긴 시간 동안, 이로 인해 로드형 이상한 상황. 이 경우 사용자가 사용할 수 있도록 하는 리디스포사블 구현하십시오 호츨 폐기 () 또는 () 를 사용하는 것이 정말 빨리 GC 의존하지 않고도 smartupdate 연결이 끊길 수 있는 훨씬 나중에 실행하십시오.
일반적으로 리디스포사블 와 함께 사용할 수 있는 모든 클래스에 대한 비관리 리소스에는 구현됩니다.
진짜 이유는 .net 설계되지 않았기 때문에 가비지 컬렉션 , 비관리 리소스에는 수집하십시오 따라서 클린업합니다 리소스에는 여전히 손에 거짓한 개발자. 또한 객체에는 않습니다를 피나리저스 때 자동으로 불렀으매 댁이라면 객체에는 아웃해야 내시경이요 어떤 이들은 GC 에서 불렀으매 undetermined 하게하면서요. # 39 라는 GC doesn& 및 오면 바로 다음 라운드 정보기술 (it), t 실행하십시오 기다리는 시간이 더 좋은 일 선고해 원거리일수록 클린업합니다 아닌 경우 객체에는 부족한 비관리 리소스 (예: 파일 또는 네트워크 연결) 하고 있다. 일회용 패턴화합니다 수동으로 입력할 수 있는 자료는 microsoft. 정해진 시간이 부족한 릴리스에는 개발자 (호출할 때 유로비치. 폐기 () 또는 사용 (.) 문). (이), 그c수프레스피나리즈 호출하십시오 것을 명심해야 합니다. 처분할 수 있는 방법을 알려줄 수 있는 # 39 는 GC 객체에는 수동으로로 폐기합니다 및 shouldn&, t be 마무리된다. 나는 k 와 b 에 대해 제안하세요 너회가 시행하십시오 레임워크 설계 지침을 스와리나 에이브럼스 책이다. 잘 쓸 수 있는 패턴을 대해 설명합니다.
굿 럭!
이 상투적이고 설명:
일부 가이드라인이며 완료하십시오 구현하는 방법:
일부 가이드라인이며 구현하는 폐기 방법:
디스커처와 디스포저 메서드가 필요한 객체는 관리되지 않는 리소스를 사용하고 있습니다. 따라서 가비지 수집기는 이러한 리소스를 정리할 수 없으며 사용자가 직접 정리해야 합니다.
IDisposable에 대한 MSDN 문서를 참조하세요(http://msdn.microsoft.com/en-us/library/system.idisposable.aspx).
이 예제에서는 관리되지 않는 핸들러인 IntPr을 사용합니다.
몇 가지 특정 동작을 수행하는 데 필요한 경우가 있을 수 있습니다 (거의) 때 더 이상 사용되지 않으며, 내가 순결케 관리됨 객체에는 can& # 39, 예를 들어 t come up with 끕니까 상단형 머리는요 하지만 난 몇 년 동안 사용하는 사례가 없지 않은가. 그러나 무엇보다 중요한 것은 어떤 자료가 객체에는 클린업합니다 비관리 사용할 수 있습니다.
따라서 일반적으로 전날에약혼자에게 won& # 39, t / 완료하십시오 패턴을 사용하지 않는 경우에는 비관리 리소스에는 처리를 사용할 필요가 있습니다.
Net 에서 개체를 .net 쓰레기요 모음기 처리하는 방법을 계시나니 관리됨 런타임용으로 개발하십시오. 그러나 유엔 관리 처분할 패턴 (리디스포사블) 는 주로 사용되는 응용 프로그램에서 객체에는 사용하고 있습니다.
즉, 닷넷 (.net) 기반 런타임용으로 개발하십시오 doesn& t # 39, 어떻게 대처해야 할지 반드시 모든 유형의 디바이스이거나 처리하십니까 거기에 (닫기와 네트워크 연결, 파일 핸들, 그래픽 장치 등), 그래서 리디스포사블 사용하는 방법 제공, let me 라고 " 구현하십시오 내 일부 클린업합니다 own". 받을시간은 유형:. 처분할 수 있도록 하는 것을 보고, 가비지 컬렉터 () 와 구축현 호출하십시오 외부에서 복구하였습니다 관리됨 힙 있다.