Verständnisproblem GC und Destruktor



  • Hallo,

    ich habe ein Verständnisproblem mit dem GC.

    In bin gewohnt, das wenn eine Klasse aus dem Sichtbarkeitsbereich läuft, der Destruktor aufgerufen wird. Nun wird mir durch den GC sugeriert, das ich mich um die Zerstörung der Klasse nicht mehr kümmern muss, also ich mit gcnew erzeugte Objekte von sich aus zerstört werden. Leider hab ich dennoch irgendwie Löcher in den Resourcen.

    ref struct A
    {
    	~A(){Console::WriteLine("~A"); System::IO::File::Open("C:\\classA_D.txt",System::IO::FileMode::CreateNew);}
    	!A(){Console::WriteLine("!A"); System::IO::File::Open("C:\\classA_F.txt",System::IO::FileMode::CreateNew);}
    };
    ref struct C
    {
    	~C(){Console::WriteLine("~C"); System::IO::File::Open("C:\\classC_D.txt",System::IO::FileMode::CreateNew);}
    	!C(){Console::WriteLine("!C"); System::IO::File::Open("C:\\classC_F.txt",System::IO::FileMode::CreateNew);}
    };
    
    ref struct B
    {
    	A ^a;
    	C ^c;
    	B(){a = gcnew A;c = gcnew C;}
    	~B(){Console::WriteLine("~B");delete a;} // c einfach leben lassen
    };
    
    int main(array<System::String ^> ^args)
    {
    	{ // Künstlichen Lebensraum erschaffen
    		B b;
    		Console::WriteLine(L"Hello World");
    	}
        return 0;
    }
    

    Da der GC erst zu zuschlagen scheint, wenn alles beendet ist, erstelle ich Dateien bei der Zerstörung um zu sehen was aufgerufen wird.

    Aus obrigen Code komme ich zum Schluss das ich leicht Resourceleaks generieren kann. (so hab ich z.B. bis eben das Problem gehabt, das Dateien nicht gelöscht wurden, die im Destruktor gelöscht werden sollten oder MS Word offen geblieben ist obwohl der Desturktor das zu machen sollte. Ja, ich hab kein delete abgesetzt, das sollte ja der GC für mich erledigen).

    IMHO müsste ich nun ~T und !T implementieren um eine ordentliche Zerstörung zu gewährleisten. Ist nur !T implementiert und ich setze manuell ein delete ab (weil sich das einfach gehört ;o) , laufe ich auch Gefahr leaks zu generieren.

    Implementiere ich nur ~T und es wird ein delete vergessen schützt mich der Garbage Collector nicht vor leaks. Aber genau das sollte doch eigentlich der GC leisten, das ich mir als Entwickler keine sorgen darum machen muss.

    Nun wird das ganze einfach nur komplexer für mich, da ich die Zerstörung der Objekte in einem (noch) unbekannten System schwer kontrollieren kann. Ich würde im Moment eine eigene Methode schreiben für das Freigeben von Resourcen die ich in ~T und !T aufrufen kann.

    Auch wenn das jetzt keine wirkliche Frage darstellt, ist es vllt möglich das es jemanden helfen kann und / oder jemand noch Wertvolle Tips dazu beitragen kann.

    Hier der Artikel der mich nach etwas suchen zum !T() brachte. Leider ist mein Egnlisch nicht so gut (vllt. daher auch noch zusätzlich verwirrung):

    ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.de/dv_vclang/html/0d09d3f1-13a0-4041-8178-402aad667edd.htm



  • Ok,

    der o.G. Artikel gibt viel viel Information 🤡

    In manchen Fällen empfiehlt es sich, den Programmierern bei der Verwendung eines Objekts die Möglichkeit zu geben, diese externen Ressourcen explizit freizugeben, bevor die Garbage Collection das Objekt freigibt. Wenn eine externe Ressource knapp ist oder die Leistung beeinträchtigt, kann eine Leistungssteigerung erzielt werden, wenn der Programmierer Ressourcen explizit freigibt, sobald sie nicht mehr verwendet werden. Um eine explizite Steuerung bereitzustellen, implementieren Sie die Dispose-Methode, die von der IDisposable-Schnittstelle bereitgestellt wird. Der Consumer des Objekts sollte diese Methode aufrufen, wenn sie das Objekt nicht mehr verwendet. Dispose kann auch dann aufgerufen werden, wenn andere Verweise auf das Objekt aktiv sind.

    ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.NETDEVFX.v20.de/dv_fxdesignguide/html/31a6c13b-d6a2-492b-9a9f-e5238c983bcb.htm

    Wer also , wie ich, bisher so blind in die Materie gelaufen ist, sollte sich das ganze unbedingt mal durchlesen. Das vermeidet einiges an Problemen und zeigt auf, wie man mit dem GC umgehen sollte 🤡

    Die verständnisprobleme kamen u.A. zustande, weil vom VC in den Klassen nur ein ~T generiert wird und kein !T , so das man den Destruktor wie gewohnt verwendet.


Anmelden zum Antworten