Laden...

Sollte der GC nicht bei this.Close den nicht mehr benötigten Speicher freigeben?

Erstellt von King-Malkav vor 14 Jahren Letzter Beitrag vor 14 Jahren 6.323 Views
King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 14 Jahren
Sollte der GC nicht bei this.Close den nicht mehr benötigten Speicher freigeben?

Hallo Leute,

ich habe mal ein kleines Problem...

Ich habe eine Anwendung die Öffnet ein neues Form. Auf dem neuen Form wird mit einem Backgroundworker eine Suche durchgeführt und die Ergbnisse in ein DataTable geschrieben. Das wiederum an ein DataGridView Gebunden ist. Je nach Suchstring geht die Speicherauslastung recht hoch. Also schonmal bis zu 1 GB Speicherbedarf.

Durch klicken des Schließen Buttons wird der Backgrundworker abgebrochen und wenn er beendet wurde lasse ich das Form über this.Close schließen.

Leider bleibt der Speicherbedarf laut Task Manager bei 1 GB und geht auch nicht mehr runter. Wie kann ich das verhindern? Sollte der GC nicht bei this.Close den nicht mehr benötigten Speicher freigeben?


 private void bgwMain_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled != true)
            {
                try
                {
                    if (textBox1.Text.Length != counter)
                    {
                        counter = textBox1.Text.Length;
                        l_titel.Text = "Searching ...Please Stand By";
                        bgwMain.RunWorkerAsync();
                    }
                    else
                    {
                        if (dt2.Rows.Count > 0)
                        {
                            dataGridView1.DataSource = dt2;
                            l_titel.Text = "Found " + dt2.Rows.Count.ToString() + " Items";
                            pb_wait.Visible = false;
                        }
                        else
                        {
                            l_titel.Text = "Nothing Here!";
                            dataGridView1.DataSource = dt2;
                            pb_wait.Visible = false;
                        }
                    }
                }
                catch (NullReferenceException)
                {

                }
            }
            else
            {
                
                t_fadeout.Enabled = true;

            }
          
        }


  void t_fadeout_Tick(object sender, EventArgs e)
        {
            if (Properties.Settings.Default.fade == true)
            {
                if (this.Opacity > 0)
                {
                    this.Opacity = Opacity - 0.05;
                }
                else
                {
                    this.Opacity = 0;
                    t_fadeout.Enabled = false;
                    this.DialogResult = DialogResult.OK;
                    this.Close();
                }
            }
            else
            {
                this.Opacity = 0;
                t_fadeout.Enabled = false;
                this.Close();
            }
        }


Danke im Vorraus... LG

5.742 Beiträge seit 2007
vor 14 Jahren

Hallo King-Malkav,

der Taskmanager sagt nichts über den tatsächlich benötigten Speicherplatz aus.

Profile mal deine Applikation - dann siehst du schnell, wie viel Speicher tatsächlich benötigt wird.

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 14 Jahren

@ winSharp93

Danke für deine Schnelle Antwort...

Hast du auch eine Profiler Empfehlung für mich?

LG

5.742 Beiträge seit 2007
vor 14 Jahren

Hast du auch eine Profiler Empfehlung für mich?

Relativ weit verbreitet sind Redgate ANTS und JetBrains dotTrace (beide kostenpflichtig).

Es gibt IMHO auch noch einen kostenlosen Profiler, ich weiß aber nicht mehr genau, wie der heißt.

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 14 Jahren

Danke, ich teste mal den ANTS, wenn der gut ist, muss ich mal mit meinem Chef sprechen, wegen Lizenzen und so...

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo King-Malkav,

Sollte der GC nicht bei this.Close den nicht mehr benötigten Speicher freigeben?

grob gesprochen sind Close und Dispose für unverwaltete Ressourcen zuständig, wogegen der GC für verwaltete Ressourcen zuständig ist. Beides hat also relativ wenig miteinander zu tun. Insbesondere bewirkt Close/Dispose nicht, dass das Objekt durch den GC freigegeben wird. Ob ein Objekt freigegeben wird, entscheidet der GC aufgrund noch vorhandenen der Referenzen auf ein Objekt völlig unabhängig davon, ob Close/Dispose aufgerufen wurde oder nicht.

herbivore

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 14 Jahren

OK. Danke. Das Problem daran ist, dass ich ein Rahmenloses Form verwende und somit nicht über das X schließen kann. Deshalb schließe ich über this.close und einem Imagebutton. bzw. über den t_fadeout_Tick...

Wie kann ich herrausfinden ob noch Referenzen auf das Objekt vorhanden sind.
Ich programmiere eigentlich hauptsächlich asp.net Sachen und bin deshalb mit Windows Forms nicht so fit...

Danke

328 Beiträge seit 2006
vor 14 Jahren

Das kannst du z.B. mit den Profiler von redgate herausfinden. Ist ein echt hilfreiches Programm.

Träume nicht dein Leben sondern lebe deinen Traum.
Viele Grüße, David Teck

Gelöschter Account
vor 14 Jahren

es gibt eine reihe von opensource .net profiler... manche auch komplett in c# realisiert... einfach mal googeln

1.346 Beiträge seit 2008
vor 14 Jahren

Das der GC nichts freigibt, liegt daran, dass noch eine referenz auf das Objekt vorhanden ist. Wenn du also die Form = null setzt und nirgenz einen anderen verweiß hast, besteht kein verweiß mehr und der GC gibt den Speicherplatz frei, sobald er anderweitig gebraucht wird. du kannst das freigeben mit GC.Collect() erzwingen

Gelöschter Account
vor 14 Jahren

du kannst das freigeben mit GC.Collect() erzwingen

do NOT use!

es gibt nu 0,000001 prozent der anwendungen, die das gerechtfertigt benötigen. deswegen exisitert es. benutzt du es dennoch machst du deine anwendung nur ineffizienter und langsamer und erreichst dadurch nur das komplette gegenteil.

1.346 Beiträge seit 2008
vor 14 Jahren

Da hast du recht. Wollte eigendlich nur sagen das es existiert. Allerdings gibt es Anwender die es nicht sonderlich gut finden wenn eine Anwendung laut Task Manager an die 1gb verbrauchen. Sie kennen ja den technichen Hintergrund nicht. Woher auch.

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 14 Jahren

Also ich habe das GC.Collect() mal spaßeshalber im Event des ersten Forms eingebaut, wenn das 2. Form geschlossen wird, dann räumt der auch anständig auf und es wird wieder über 1 GB Ram frei. Ich habe es aber wieder raus genommen. Generell sollte ich die Suchanfrage auf 10000 Ergebnisse beschränken. Kein normaler User sucht in einem iTunes Archiv mit über 20000 Titeln nach allen Songs die ein a beinhalten...

Laut dem ANTS Memory Profiler räumt er auch beim 2 Aufruf des Forms auf, wenn er dann über 1,5 GB Ram Auslastung kommt...

Nur ich dachte, der GC räumt zyklisch auf? Das scheint nicht zu passieren oder ich habe einfach nicht lange genug gewartet oder was falsch verstanden...

328 Beiträge seit 2006
vor 14 Jahren

Der GC räumt meines Wissens dann auf, wenn es notwendig ist, also wenn der Speicher langsam knapp wird.

Träume nicht dein Leben sondern lebe deinen Traum.
Viele Grüße, David Teck

Gelöschter Account
vor 14 Jahren

kein mensch braucht freien speicherplatz...... wenn er benötigt wird, wird er auch freigegeben....

S
8.746 Beiträge seit 2005
vor 14 Jahren

Hier erzählt mal einer der GC-Gurus von MS wann es Sinn macht (!) den GC manuell aufzurufen:

Maoni's WebLog - CLR Garbage Collector: When memory is running low…

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo svenson,

der dort beschriebene Fall ist so speziell und es werden selbst in diesem Fall gleich wieder soviele Einschränkungen gemacht, dass man mit Fug und Recht bei der allgemeinen Aussage, dass man CG.Collect nie selbst aufrufen sollte, bleiben kann. Das ist für sicher für mehr als 99,9% der Fälle die beste Lösung.

herbivore

Gelöschter Account
vor 14 Jahren

gc.collect macht nur dann sinn, wenn man viel mit großen bildern arbeitet. z.b. im medizinischen bereich, wenn viel mit digitalen röntgenbildern gearbeitet wird und man eine starke fragmentierung des LOH zuvorkommen möchte (zusätzlich kommt noch hinzu das man die bilder oft im speicher pinnen muss, da man auch filter über die großen bilder laufen lässt...). da ist es oft so, das die outofmemoryexception recht schnell kommt.... und auch dort muss man sich ganz präzise darüber gedanken machen, wann man den lauf durchführt und wann lieber nciht...