Garbage Collector ?



  • Hallo Leute,

    das mag eine ganz einfache Frage sein, aber ich will später kein Speicherfresser produzieren.
    folgender Code:

    public class myClass
    {
       public infoObject info;
       ...
       public void GetInfo()
       {
          info = infiClass.GetInfo();
       }
    }
    

    Wenn ich jetzt meine Funktion GetInfo() mehrfach aufrufe, wird der vorherige Inhalt von info behalten und neuer Speicher abgelegt oder löscht er das alte Objekt bevor ein neues angelegt (zurückgeliefert) wird?

    VG
    Ranger



  • Hallo,

    ich weiß jetzt nicht wie deine Klasse "infoObject" aufgebaut ist, aber Prinzipiell ist es erstmal so, dass Objekte auf die nicht verwiesen wird mit dem Durchlauf des GC weggeräumt werden.

    Ausnahmen bilden hier Objekte, die intern Unsafe-Zugriffe besitzen (z.B. FileStreams, Netzwerkverbindungen etc.). Darum werden diese Klassen mit dem IDisposable-Pattern implementiert. - Um das Disposen sollte man sich dann jedoch auch Zeitnah kümmern, wenn das Objekt nicht mehr benötigt wird.



  • Danke für die Info.
    Offensichtlich hat die Klasse infoObject hier keine Dispose() Funktion. Sie stammt nicht von mir, ich hab sie über eine dll eingebunden. Ich weiß also nicht genau, was darin passiert. Bleibt wahrscheinlich nur, Programm testen und sehen, was an Speicher verbraucht wird.

    VG

    Ranger



  • Naja,

    die Klasse hat ja sicher eine Aufgabe die du kennst. - Sind dort irgendwelche Resourcen-Zugriffe aus deiner Sicht notwendig damit die Klasse die Arbeit erledigen kann? Wenn es tatsächlich nur eine "Info"- und somit eine reine Datenklasse ist wird da wohl nichts intern passieren.



  • inflames2k schrieb:

    Hallo,

    ich weiß jetzt nicht wie deine Klasse "infoObject" aufgebaut ist, aber Prinzipiell ist es erstmal so, dass Objekte auf die nicht verwiesen wird mit dem Durchlauf des GC weggeräumt werden.

    Ausnahmen bilden hier Objekte, die intern Unsafe-Zugriffe besitzen (z.B. FileStreams, Netzwerkverbindungen etc.). Darum werden diese Klassen mit dem IDisposable-Pattern implementiert. - Um das Disposen sollte man sich dann jedoch auch Zeitnah kümmern, wenn das Objekt nicht mehr benötigt wird.

    Die bilden keine Ausnahme. Das Disposable Pattern ist nur dazu da, dass der Benutzer die Kontrolle darüber behält, wann die (externen) Ressourcen freigegeben werden. Wenn eine Klasse per WinApi Speicher anfordert, dann bleibt der bestehen, wenn auf die Klasse nicht mehr referenziert wird und die GC die Klasse wegräumt. Der (externe) Speicher würde dann erst mit Beendigung des Programms vom Betriebssystem aufgeräumt werden. Auch Disposable würde in dem Fall nichts bringen, da Dispose nicht automatisch vom GC aufgerufen wird. Erst wenn man zusätzlich noch den Finalizer implementiert und dieser intern Dispose aufruft, wird der (externe) Speicher "automatisch" durch die GC freigegeben. Allgemein sollte man sich aber selbst um den Dispose Aufruf kümmern und den impliziten Aufruf durch Finalizer dann mit einem GC.SuppressFinalize unterdrücken.



  • Ich habe nie geschrieben, dass der GC Dispose aufruft. - Drum ja auch meine Aussage dazu, dass diese Zeitnah spätestens wenn die Resourcen nicht mehr gebraucht werden Dispose aufgerufen werden sollte.

    Außerdem geht es hier ja um das wegräumen des Speichers und das passiert halt nicht solange die externe Resource offen ist. Nicht mehr und nicht weniger habe ich geschrieben. - Insofern bilden Klassen mit externen Resourcen eben oben genannte Ausnahme, da der Nutzer dafür Sorge zu tragen hat, das die Resourcen geschlossen werden.

    EDIT: Zusatzinfo:
    Es ist übrigens in keinem Fall sichergestellt, wann Objekte weggeräumt werden. Das hängt ganz vom GC ab. Das reine entfernen aller Verweise auf das Objekt ist also noch kein bereinigen des Arbeitsspeichers.



  • Du hast geschrieben, "dass Objekte auf die nicht verwiesen wird mit dem Durchlauf des GC weggeräumt werden. Ausnahmen bilden hier Objekte, die intern Unsafe-Zugriffe besitzen". So wie das da steht ist es falsch, weil auch Objekte, die intern "Unsafe-Zugriffe" besitzen, weggeräumt werden.



  • Glasgow_Ranger schrieb:

    Ich weiß also nicht genau, was darin passiert. Bleibt wahrscheinlich nur, Programm testen und sehen, was an Speicher verbraucht wird.

    Kannst ja einfach gucken ob 2x das selbe Objekt zurückkommt.
    Wenn ja is vermutlich relativ wurst wie oft du GetInfo() aufrufst. Wenn nein, dann wird immer ein neues Objekt angelegt, d.h. ein GetInfo() Aufruf ist zumindest nicht ganz gratis.

    public class Foo
    {
       public void Test()
       {
          var a = infiClass.GetInfo();
          var b = infiClass.GetInfo();
          var distinctObjects = !object.ReferenceEquals(a, b);
       }
    }
    

    Und: Guck dir die Methode mit einem IL-Disassembler an wenn du es genau wissen willst. Dann siehst du genau was die macht.



  • KN4CK3R schrieb:

    So wie das da steht ist es falsch, weil auch Objekte, die intern "Unsafe-Zugriffe" besitzen, weggeräumt werden.

    Im allgemeinen ging es ja aber um den durch die Objekte verwendeten Speicher und der wird eben nicht weggeräumt wenn die Resourcen noch offen sind. Das ist das einzige was in meiner Aussage fehlt: Die Resourcen müssen geschlossen sein damit der Speicher freigegeben wird.



  • @inflames2k
    Hä? 😕
    Natürlich werden auch Objekte weggeräumt die nen Finalizer haben. Nur halt typischerweise einen GC Durchlauf später. Weil halt erst noch der Finalizer laufen muss.



  • Danke Leute für die Hinweise.
    Ich werd mir das mal genau ansehen und am Rückgabewert sehen, ob es das gleiche Objekt mit neuen Werten ist oder eine neues.

    VG
    Ranger



  • hustbaer schrieb:

    @inflames2k
    Hä? 😕
    Natürlich werden auch Objekte weggeräumt die nen Finalizer haben. Nur halt typischerweise einen GC Durchlauf später. Weil halt erst noch der Finalizer laufen muss.

    Habe ich irgendwo etwas anderes behauptet?


Anmelden zum Antworten