2009-04-23 3 views
1

그물에서 비트 맵으로 직접 스트리밍하여 이미지에로드하는 것을 기억합니다. 스트림을 닫아, 비트 맵을 돌려 주어 이미지 컨트롤에 보관 유지합니다.GC와 IDispose는 C#에서 어떻게 작동합니까?

나는 loadPicture()를 제외하고는 스마트 포인터가 C++에서하는 것처럼 첫 번째 비트 맵이 해제됩니다. 그러나 그것은 내가 처분 할 때까지 많은 숫양을 소비했습니다. 그래서 제 질문이 있습니다.

GC 및 Dispose 가능한 개체는 C#에서 어떻게 작동합니까? 왜 smart_ptr처럼 구현되지 않습니까?

답변

2

런타임이 필요할 때 GC가 실행됩니다.

기본 규칙은 다음과 같습니다. Disposable type (IDispose)을 사용하는 경우 프로그래머는 가능한 한 빨리 해당 유형에서 사용하는 리소스를 해제해야합니다. 더 이상 사용하지 않을 때 Dispose를 호출해야합니다. 그 타입. 예를 들어, 파일을 읽을 때 파일을 읽는 즉시 파일을 닫습니다. (close를 호출하면이 경우 dispose가 호출됩니다.)

8

참조는 스마트 포인터가 아닙니다. 참조 변수가 범위를 벗어나 다른 값으로 바꾸거나 null로 설정하는 것은 모두 이 아닌입니다. 이것은 단순히 CLI/GC 디자인의 일부입니다

...

Gargage 컬렉션 (GC)을 필요로 할 때 를 실행하고 사용하는 관리되는 메모리를 정리해야하고, (파이널 라이저가 제공되는 경우) 관리되지 않는 리소스도 있습니다. 그러나 결정 론적 정리의 경우 그 목적은 IDisposable입니다. using을 통해 완료하거나이 책임을 맡은 다른 항목 (예 : 스트림/리더기와 같이 일반적)으로 넘겨 주면 작업 할 때 Dispose()과 같은 작업을 수행해야합니다.

using (StreamReader reader = new StreamReader(myfile))) 
{ 
    ... 
} 
+0

+1입니다. 확실하게이 질문이 벌써 물었다라고 확신한다 :) –

+0

나는 당신에게 무엇이라도 처분 할 필요가 없다고 말하고 있냐? –

+0

당신이하지 않더라도 리소스가 결국 해제됩니다 (즉, IDisposable을 올바르게 구현 한 경우). 실제로 이는 안전망에 불과합니다. 가능한 한 빨리 관리되지 않는 리소스를 해제하려고합니다. –

0

smart_ptr는 참조 카운트입니다. 이를 통해 코드에서 더 이상 참조되지 않을 때 리소스를 결정적으로 릴리스 할 수는 있지만 자신의 문제가 있습니다. 참조를 지정하면 카운터가 항상 업데이트되어야하며 순환 참조가 자동으로 해제되어 메모리 누수가 발생하고 메모리 관리자가 더 자주 호출됩니다.

.NET의 GC는 포괄적 인 수집기입니다. 메모리가 해제되어야한다고 생각할 때 (일반적으로 메모리 사용 조건에 의해 트리거되지만 결정적이지는 않음) 시스템에서 모든 활성 참조 목록을 작성하여 시작합니다 (CPU 레지스터, 중첩 참조 등 포함).). 이것은 포인터 연산 등을 할 수없는 관리 환경에 있기 때문에 가능합니다. 시스템은 모든 참조를 추적 할 수 있습니다. 라이브 참조 목록이 작성되면 기본적으로 더 이상 사용되지 않는 모든 메모리가 해제됩니다. 물론 이것은 단지 기본적인 스케치 일뿐입니다. 관리되지 않는 리소스의 효율성과 관리를 위해서는 개체 생성, 종결 자 등이 더 있습니다.하지만 작동 원리에 대한 기본적인 이해에는 중요하지 않습니다.

IDisposable 인터페이스는 일회용 패턴을 구현하는 데 사용되며 결정적 방식으로 처리해야하는 개체로 작업 할 때 유용합니다. 이 패턴은 개체가 더 이상 필요하지 않을 때 Dispose()가 명시 적으로 호출되므로 관리되지 않는 리소스를 해제하거나 핸들 등을 닫을 수는 있지만 메모리를 해제하지는 않습니다. 이것은 GC에 의해 나중에 수행 될 것이지만, 결정적 릴리스의 자원이 이미 수행 되었기 때문에 나중에 발생하는 것은 중요하지 않습니다.

1

IDisposable을 구현하는 모든 객체에서 Dispose explicity를 호출해야합니다. 그렇지 않으면 관리되지 않는 리소스 이 처리되지 않습니다.. 명시 적으로 호출하지 않으려면 Dispose 메서드를 호출하기 위해 Finalize 메서드를 재정의해야합니다. 즉, 다음과 같이 자주 표시됩니다.