Endlos Backgroundworker memory problem



  • Ich nehme an Du hast noch nicht gedebuggt, wenn ein Fehler aufgetreten ist. Wäre ja mühsam so lange zu warten.

    Nun, wenn ich dich recht verstanden habe, dann ruft OnWork die Methode DoWork auf, welche wiederum OnWork aufruft, usw.

    Vereinfacht so, natürlich mit Abbruch Kriterium und den Sleep's.
    Edit: (Sorry habs nur in C#)

    using System;
    using System.Windows.Forms;
    using System.ComponentModel;
    
    namespace Test
    {
    	public partial class MainForm : Form
    	{
    		private BackgroundWorker worker = new BackgroundWorker();
    
    		public MainForm()
    		{
    			InitializeComponent();
    		}
    
    		private void Button1Click(object sender, EventArgs e)
    		{
    			worker.DoWork += new DoWorkEventHandler(OnWork);
    			worker.RunWorkerAsync();
    		}
    
    		private void DoWork(object sender,  DoWorkEventArgs e)
    		{
    			DoWork(sender, e);
    		}
    
    		private void OnWork(object sender,  DoWorkEventArgs e)
    		{
    			OnWork(sender, e);
    		}
    	}
    }
    

    Dies verrusacht einen Stackoverflow, weil es ein Rekursiver Aufruf ist.

    Gruss Simon



  • Du kannst das einfach testen, indem Du alle Sleeps rausnimmst und nur noch die gegenseitigen Aufrufe drin lässt. Dann passiert nämlich genau das, was mit den Sleeps 4-5 Tage dauert, innert (milli) sekunden.



  • ja denke auch dass es daran lag.

    bis jetzt war es so dass onwork sich immer wieder aufgerufen hat und Dowork eben nix gemacht hat.

    jetzt ruft onwork dowork auf und das ruft onwork wieder auf und nun scheint´s zu passen.

    CU



  • jetzt ruft onwork dowork auf und das ruft onwork wieder auf und nun scheint´s zu passen.

    Was heisst passen?
    Wenn OnWork -> DoWork -> OnWork -> DoWork -> ... ist es überhaupt nicht besser als OnWork -> OnWork -> OnWork -> ...

    Es gibt eine StackOverflowException !



  • hmm eben nicht. jetzt wächst der speicher an und wird dann wieder nach einiger zeit reduziert.

    liegt glaub ich daran:

    worker = New System.ComponentModel.BackgroundWorker()
    
                AddHandler worker.DoWork, New _
                   System.ComponentModel.DoWorkEventHandler(AddressOf OnWork)
    

    CU



  • ABstraCT schrieb:

    liegt glaub ich daran:

    worker = New System.ComponentModel.BackgroundWorker()
    
                AddHandler worker.DoWork, New _
                   System.ComponentModel.DoWorkEventHandler(AddressOf OnWork)
    

    CU

    Also an was jetzt genau von dem Code?
    Das machst Du doch nur einmal zu Begin, oder?



  • hmm ich glaub ich habe da eh nen denkfehler drin !
    irgendwie dachte ich mann muss die onwork immer wieder aufrufen aber eigentlich reicht es ja alles dann in ner schleife mit den sleeps ablaufen zu lassen ohne irgendwas wieder aufrufen zu müssen.

    CU



  • Ja, dann wird aus der rekusion eine iteration und das ist sehr viel besser im hinblick auf die StackOverflowException.
    Grüsse
    Simon



  • ABstraCT, Du zeigst uns das Skelett und wir sollen die Leber untersuchen?

    Wenn ich mir das so anhöre, könnte ich wetten, dass Du sowohl in DoWork als auch in OnWork direkt auf Instanz-Variablen zugreifst. Stimmt das? Well, in diesem Fall scheppert das Design Deiner Anwendung ganz laut. Und die Idee mit den Sleeps beeinträchtigt die Performanz des ganzen Systems. Verwende Timer. New-e deine Variablen in WorkerThread. Und nach Ablauf einer Arbeitsrunde verwende:

    GC.Collect();
    GC.WaitForPendingFinalizers();
    GC.Collect();
    

    Der GC macht seine Arbeit ganz gut. Wenn er nur dazu kommen darf. Und was der Task-Manager über den Verbrauch von Speicher sagt, ist nicht immer wörtlich zu nehmen. Woher weißt Du überhaupt, dass dein Programm ein Speicher-Problem hat? Wirft die Anwendung einen Ausnahmefehler (MemoryOutofRangeException, OutOfMemoryException usw.)? Verwendest Du System-Ressourcen (Handles etc.)? Wenn es einen Crash gibt, was steht dann im System-Log?

    Fragen über Fragen. Poste wirklichen Code und wirkliche Fehlermeldungen, dann kann Dir vielleicht auch wirklich geholfen werden.



  • Wieso beeinflusst das Sleep das gesamte System ?



  • maro158 schrieb:

    ABstraCT, Du zeigst uns das Skelett und wir sollen die Leber untersuchen?

    Wenn ich mir das so anhöre, könnte ich wetten, dass Du sowohl in DoWork als auch in OnWork direkt auf Instanz-Variablen zugreifst. Stimmt das? Well, in diesem Fall scheppert das Design Deiner Anwendung ganz laut. Und die Idee mit den Sleeps beeinträchtigt die Performanz des ganzen Systems. Verwende Timer. New-e deine Variablen in WorkerThread. Und nach Ablauf einer Arbeitsrunde verwende:

    GC.Collect();
    GC.WaitForPendingFinalizers();
    GC.Collect();
    

    Der GC macht seine Arbeit ganz gut. Wenn er nur dazu kommen darf. Und was der Task-Manager über den Verbrauch von Speicher sagt, ist nicht immer wörtlich zu nehmen. Woher weißt Du überhaupt, dass dein Programm ein Speicher-Problem hat? Wirft die Anwendung einen Ausnahmefehler (MemoryOutofRangeException, OutOfMemoryException usw.)? Verwendest Du System-Ressourcen (Handles etc.)? Wenn es einen Crash gibt, was steht dann im System-Log?

    Fragen über Fragen. Poste wirklichen Code und wirkliche Fehlermeldungen, dann kann Dir vielleicht auch wirklich geholfen werden.

    Es hat sich doch schon gestern geklärt das es kein Speicherproblem sondern ein Stack Overflow war ausgelöst durch eine endlos rekursion.



  • Abgesehen dass das Problem ein StackOverlow war, würde ich den GC nie (sag nie nie) direkt beeinflussen (GC.xxx).
    Gruss Simon



  • Knuddlbaer schrieb:

    Wieso beeinflusst das Sleep das gesamte System ?

    Beim Aufruf von Sleep findet ein Übergang aus dem User- zum Kernel-Mode statt. Das ist teuer.



  • simon.gysi schrieb:

    Abgesehen dass das Problem ein StackOverlow war, würde ich den GC nie (sag nie nie) direkt beeinflussen (GC.xxx).
    Gruss Simon

    Manchmal gibt es keine Alternative dazu. Angenommen du hast einen Timer, der alle x Stunden eine Aktivität auslöst. Anschließend passiert nichts mehr außer Warten auf das Auslösen des Timers. Wann glaubst Du dass der GC wieder einspringt?

    Gruss
    maro158



  • Es hat sich doch schon gestern geklärt das es kein Speicherproblem sondern ein Stack Overflow war ausgelöst durch eine endlos rekursion.

    Ja. Aber Erkenntnis ist der beste Weg zur Besserung (des Codes).
    🙂



  • Wenn es nötig ist.



  • simon.gysi schrieb:

    Wenn es nötig ist.

    Ich mag Deine sybillinische Antwort, Simon.

    Wenn 48 Stunden lang keine weiteren Speicher-Anforderungen gemacht werden, hat der GC einfach keine Möglichkeit aktiviert zu werden. Der Speicher bleibt "wie er immer war, nur einsam und verlassen" (Nena) ...



  • OT: Was bedeutet sybillinisch?
    Edit: Habs gefunden.. http://www.duden-suche.de/suche/trefferliste.php?suche=einfach&treffer_pro_seite=10&modus=title&level=125&senden=suchen&suchbegriff[AND]=sibyllinisch

    1. si|byl|li|nisch <Adj.> (bildungsspr.): geheimnisvoll, rätselhaft: -e Worte.



  • simon.gysi schrieb:

    OT: Was bedeutet sybillinisch?
    Edit: Habs gefunden.. http://www.duden-suche.de/suche/trefferliste.php?suche=einfach&treffer_pro_seite=10&modus=title&level=125&senden=suchen&suchbegriff[AND]=sibyllinisch

    1. si|byl|li|nisch <Adj.> (bildungsspr.): geheimnisvoll, rätselhaft: -e Worte.

    Die Sibyllen waren in der griechischen Antike Wahrsagerinnen, berühmt für ihre doppeldeutigen Antworten, aus denen jeder entnehmen konnte, was er für richtig hielt. Der Trick besteht in der Erstellung einer möglichst großen Projektionsfläche für die Phantasie des Deuters. Ganz einfach ist es, indem man kurze, sehr allgemeine Sätze verwendet.



  • maro158 schrieb:

    Wenn 48 Stunden lang keine weiteren Speicher-Anforderungen gemacht werden, hat der GC einfach keine Möglichkeit aktiviert zu werden. Der Speicher bleibt "wie er immer war, nur einsam und verlassen" (Nena) ...

    Was totaler Unsinn ist weil die GC der .Net-Frameworks nicht durch Speicheranforderungen ausgelöst wird:

    ".NET Framework includes a garbage collector which runs periodically, on a separate thread than the application's thread, that enumerates all the unusable objects and reclaims the memory allocated to them.
    "

    Ausserdem wird in der MSDN ausdrücklich davor gewarnt die GC unnötig aufzurufen:

    "Be sure that the application is not inducing garbage collection too frequently because that can decrease the performance if the garbage collector is unproductively attempting to reclaim objects. "


Anmelden zum Antworten