source

Dispose()에서 obj = null(없음)을 설정할 수 있습니까?

manysource 2023. 5. 15. 22:21

Dispose()에서 obj = null(없음)을 설정할 수 있습니까?

지정 를 사자지개다설수있정습까니할음로으체용를정?로 ?null(Nothing를 클릭합니다.NET의Dispose()방법? 요?!이것이 메모리 누수를 방지할 수 있을까요, 아니면 쓸모가 없을까요?!

두 가지 예를 들어 보겠습니다.

public class Foo : IDisposable
{
    private Bar bar; // standard custom .NET object

    public Foo(Bar bar) {
        this.bar = bar;
    }
    public void Dispose() {
        bar = null; // any sense?
    }
}

public class Foo : RichTextBox
{
    // this could be also: GDI+, TCP socket, SQl Connection, other "heavy" object
    private Bitmap backImage; 

    public Foo(Bitmap backImage) {
        this.backImage = backImage;
    }

    protected override void Dispose(bool disposing) {
        if (disposing) {
            backImage = null;  // any sense?
        }
    }
}

개인적으로 저는 두 가지 이유로 그렇게 하는 경향이 있습니다.

  • 그것은 누군가가 그것을 푸는 것을 잊었다는 것을 의미합니다.Foo됨) 개체 (으)로 표시됨)Bitmap이 경우)는 여전히 수집될 수 있습니다(미래의 어느 시점 - GC가 원할 때마다). 이것은 관리되지 않는 리소스 주변의 얕은 래퍼일 가능성이 높지만 모든 작은 도움이 됩니다.
    • 사용자가 이벤트 하나를 여는 것을 잊었다는 이유만으로 실수로 전체 객체 그래프를 계속 맴도는 것은 정말 싫습니다.IDisposable사용 가능한 모든 것을 분리하는 것은 어떻습니까?
  • 더 중요한 것은, 나는 이제 뻔뻔스럽게 이 필드를 (방법 등에서) 폐기를 확인하기 위해 사용할 수 있고, 던집니다.ObjectDisposedException 그것이 그면다라면null

의 은?Dispose()가비지 수집기에서 처리하지 않는 리소스를 정리할 수 있습니다.객체는 GC에 의해 처리되므로 일반적인 상황에서는 참조를 null로 설정할 필요가 없습니다.

가 전화를 걸 것으로 예상하는 경우입니다.Dispose 그리고 그 이후의 인스턴스를 유지합니다.이 경우 내부 참조를 null로 설정하는 것이 좋습니다.그러나 일반적으로 일회용 인스턴스는 동시에 폐기되고 릴리스됩니다.이런 경우에는 큰 차이가 없을 것입니다.

거의 쓸모가 없어요.이전 COM/VB 시절에 NULL로 설정하면 참조 카운트가 감소할 것으로 생각됩니다.

그건 사실이 아닙니다.NET. 막대를 null로 설정해도 아무것도 파괴하거나 해제하지 않습니다.막대가 가리키는 참조를 개체에서 "null"로 변경하는 것입니다.개체가 여전히 존재합니다(그러나 지금은 개체를 참조하지 않으므로 결국 가비지가 수집됩니다).거의 예외 없이, 그리고 대부분의 경우, 이것은 애초에 Foo ID를 일회용으로 만들지 않았다면 일어났을 것과 같은 일입니다.

ID Disposable의 큰 목적은 TCP 소켓이나 SQL 연결 등 관리되지 않는 리소스를 해제하는 것입니다.이 작업은 일반적으로 참조를 "null"로 설정하는 것이 아니라 관리되지 않는 리소스가 제공하는 정리 기능을 호출하여 수행됩니다.

소유된 인스턴스가 다시 사용되는 것을 방지하려면 이 방법을 사용할 수 있습니다.

일회용 필드에 대한 참조를 null로 설정하면 더 이상 인스턴스를 사용할 수 없습니다.

당신은 얻지 못할 것입니다.ObjectDisposedException또는 소유한 처분 인스턴스를 사용하여 발생한 기타 잘못된 상태(당신은 받을 수 있음)NullReferenceExceptionnull을 확인하지 않는 경우).

이것은 모든 것이 당신에게 이해되지 않을 수도 있습니다.IDisposable사물은 을 가지고 있습니다.IsDisposed재산 및/또는 투척ObjectDisposedException폐기된 후 사용할 경우 일부는 이 원칙을 위반할 수 있으며 null로 설정하면 원하지 않는 효과가 발생하지 않을 수 있습니다.

C#에서 객체를 null로 설정하는 것은 객체에 대한 참조를 해제하는 것입니다.

따라서 이론적으로 C#의 Dispose-Method에서 관리되는 개체에 대한 참조를 릴리스하는 것이 더 낫지만, GC가 해당 개체를 수집하기 전에 참조된 개체를 수집할 수 있는 가능성에 대해서만 가능합니다.둘 다 동일한 실행에서 수집될 가능성이 높기 때문에 GC는 참조된 개체가 배치된 유형에 의해서만 참조되므로 둘 다 수집될 수 있음을 가장 잘 인식할 수 있습니다.

또한 클래스가 이미 삭제된 경우 일회용 클래스의 모든 공용 구성원이 예외를 던져야 하기 때문에 참조를 공개할 필요가 매우 적습니다.따라서 참조된 메서드를 삭제한 후에는 참조된 개체에 액세스할 수 없습니다.

VB.NET에서는 다음과 같이 설정해야 합니다.Nothing선언된 객체

다음을 사용하는 처리기Handles키워드는 이 방법으로 이러한 개체에서 제거됩니다.

의 목적은dispose()관리되지 않는 리소스를 정리하는 것입니다.TCP 연결, 데이터베이스 연결 및 기타 데이터베이스 개체 및 이러한 관리되지 않는 리소스는 개발자가 폐기 방법으로 릴리스하도록 되어 있습니다.정말 말이 되는군요.

일반적으로 null로 설정할 필요가 없습니다.그러나 클래스에 재설정 기능이 있다고 가정합니다.

그런 다음 Dispose(폐기)를 두 번 호출하지 않을 수 있습니다. 일부 Dispose(폐기)가 올바르게 구현되지 않을 수 있기 때문입니다.ObjectDisposed 예외입니다.

private void Reset()
{
    if(_dataset != null)
    {
       _dataset.Dispose();
       _dataset = null;
    }
    //..More such member variables like oracle connection etc. _oraConnection
 }

언급URL : https://stackoverflow.com/questions/2280051/any-sense-to-set-obj-nullnothing-in-dispose