Announcement

Collapse
No announcement yet.

wie genau funktioniert der garbage collector?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • wie genau funktioniert der garbage collector?

    also das prinzip ist klar. gibt es keine referenzen mehr auf ein object so räumt der gc das objekt aus dem speicher.

    nur angenommen ich habe zwei oder drei objekte die untereinander agieren. damit der gc nun erkennt das eines der objekte gelöscht werden kann, muss ich nun jede referenz beseitigen?

    oder reicht es wenn die referenz in meiner main weg ist und die drei objekte nicht mehr von meinem programm erreicht werden können obwohl sie noch referenzen aufeinander besitzen?

    mfg
    Zebes

  • #2
    Hallo Zebes,

    Also für den GC ist folgendes wichtig!
    Classen die IDisposable implementieren, müssen disposed werden.
    Z.B.:
    Code:
    LinearGradientBrush _brush = new LinearGradientBrush(blablabla);
    //Hier wird etwas mit _brush gemacht.
    _brush.Dispose();
    _brush=null;
    Das 'null' setzen ist kein Muß in diesem Fall, hilft dem GC allerdings die nicht referenzierten Objekte zu erkennen.

    Wenn '_brush' Klassenglobal deklariert ist, muß unbedingt 'null' gesetzt werden, da ansonnst die Klasse immer die Referenz auf das bereits disposte Objekt behält. Zumindest solange bis wieder eine neue Instanz erzeugt wird. Wird die Klasse allerdings auch Disposed und hat noch die referenz auf '_brush', kann diese nicht vom GC abgeräumt werden.
    Ich erachte es daher als guten Programmierstil das Objekt in jedem Fall 'null' zu setzen.

    Eine andere möglichkeit ist das Benutzen von 'using' blöcken.
    Code:
    using(LinearGradientBrush _brush = new LinearGradientBrush(blablabla))
    {
        //Hier wird etwas mit _brush gemacht.
    }
    Das Objekt ist jetzt automatisch disposed und von jedlichen Referenzen befreit. Genauer gesagt wird sowohl die Dispose als auch die Close methode automatisch vom Framework aufgerufen.
    Zusätzlicher wichtiger Vorteil ist, daß man sich nicht um die Referenzen kümmern muß, wenn eine Exception auftritt.


    Das von dir beschriebene automatische Disposen vom parent zum child object, funktioniert meines Wissens nach nur bei von Control abgeleiteten Klassen, die in einer ControlCollection gespeichert sind.
    Z.B.: Du hast eine Form, auf der mehrere UserControls sind.
    Die Form wird mittels Close() geschlossen (also auch disposed, da die Close methode Dispose() aufruft), jetzt werden die UserControls auch automatisch disposed.

    Das ist allerdings keine komplette sicherheit, weil ja zusätzlich wichtig ist, waß in diesen UserControls gemacht wird (wurde).
    Jedes UserControl (und auch Klasse) sollte die:
    Code:
    protected override void Dispose( bool disposing )
    {
    	if( disposing )
    	{
    		//mach hier zusätzliche nötige Aktion
    	}
    	base.Dispose( disposing );
    }
    Methode überschreiben.
    Diese Methode wird jetzt beim Schließen der Form automatisch aufgerufen.
    Befinden sich auf deinem Control nur Referenzen innerhalb des UserControls, so wirst du warscheinlich nichts machen müssen (Außer möglicherweise das disposen und 'null'-setzen von noch bestehenden Instanzen von z.B.:LinearGradientBrush).
    Befinden sich allerdings Referenzen zu noch bestehenden Klassen in deinem UserControl (wie z.B.: Du bist mit einer von dir erstellten Management Klasse verbunden, die immer im Speicher bleiben soll), dann müßt du diese Referenz lösen. Könnte mit einem 'null' setzen erledigt sein, allerdings ist sehr wichtig auch mögliche event Handler (delegates) zu diconnecten "-=".

    Meine Empfehlung ist in jedem Fall das verwenden einer Profiling SW.
    Ich verwende den http://www.memprofiler.com/! (Hat mir schon sehr geholfen)

    Ich hoffe ich hab dir etwas weiterhelfen können.
    Grüße,

    Martin

    Comment


    • #3
      danke für die info.

      ist dir schon mal aufgefallen das die windows forms auch ein speicherproblem haben. es wird neuer speicher alokiert wenn man über einen button fährt. der wird allerdings erst wieder frei gegeben wenn wenn man das fenster verkleinert. finde ichirgend wie seltsam.

      mfg
      Zebes

      Comment


      • #4
        Hallo,

        Martins Antwort finde ich recht ausführlich und sehr verständlich. Ich möchte sie aus eigener Erfahrung und anderen Diskussionen noch um folgende Gesichtspunkte ergänzen:
        • Der GC räumt nicht ständig auf, sondern nur bei Bedarf. Vor allem bei "kleineren" Anwendungen kann man den Eindruck haben, dass diese Windows unerwartet stark aufblähen; aber solange es keinen Bedarf gibt, dies zu unterbinden, geschieht es auch nicht.
        • Die Reihenfolge beim Löschen von Objekten kann zwar beeinflusst werden, aber nicht richtig gesteuert; für den Entwickler sieht es wie zufällig aus. Deshalb kann (worauf Martin schon hinwies) in "gelöschten" Objekten nicht mehr auf darin enthaltene Objekte zugegriffen werden.
        • Dies kann unangenehme und unerklärliche Auswirkungen z.B. auf Singleton-Klassen (besonders Formulare) haben: Eine Instanz wird als gelöscht markiert, aber vom GC noch nicht bearbeitet; diese Instanz soll neu erzeugt werden, das wird vom System mit einer Zugriffsverletzung beantwortet. Auch solche Situationen werden verhindert, wenn Martins Hinweise beachtet werden.

        @Zebes
        Das erklärt vielleicht auch das letzte von Dir genannte seltsame Verhalten.

        Gruß Jürgen

        Comment


        • #5
          Hallo,

          Danke für die Ergänzung, habe verabsäumt auf das GC Verhalten einzugehen.
          Grüße,

          Martin

          Comment


          • #6
            Hallo,

            Es handlet sich hierbei sicher nur um Paint bzw. Mouse Event KLassen, die Instanziert werden aber mit Sicherheit "irgendwann" abgeräumt werden.
            So wie "Jürgen Thomas" bereits ausgeführt hat, kann dieses nicht vorhergesagt werden.

            Aber um speicherprobleme solltest du dir deswegen keine gedanken machen!
            Grüße,

            Martin

            Comment

            Working...
            X