pr0gg3r Geschrieben 11. Juli 2013 Geschrieben 11. Juli 2013 Das ist klar? Du scheinst mir eine Kristallkugel in der Tasche zu haben Natürlich nicht. Wenn wir aber die Lösung(! ) anschauen, haben wir im Thread mindestens zwei Teile: - Das Sammeln von irgendwelchen Daten (wie auch immer, das weiß nur der TE) - Das Speichern von Daten Ich zumindest würde erst einmal überprüfen, welcher Teil das Thread-Problem verursacht. Wenn es der erstere ist, muss man an dieser Stelle optimieren. Wenn es im letzteren liegt, wäre mein obriger Vorschlag eine Möglichkeit, das Thread-Problem zu beheben. Meine Kristallkugel sagt mir, dass es immer problematisch ist, zig Verbindungen zu einer DB aufzubauen (dabei könnte man auch eine Instanz einer Verbindung nutzen). Genauso problematisch ist es, eine Textdatei zig mal zu öffnen und zu schreiben, ohne zu wissen, ob noch andere Prozesse die Datei zum Schreiben geöffnet haben. Mit der TCP-Verbindung ist es genauso, was ist, wenn der Ping (warum auch immer) mal höher als 250ms ist... Also laut meiner Kristallkugel ist das gesamte Vorhaben, so wie es jetzt umgesetzt ist, sowieso kritisch einzustufen. Zitieren
NancyG Geschrieben 11. Juli 2013 Autor Geschrieben 11. Juli 2013 Ich möchte auch was sehen, wenn ich es im VS-Debugger laufen habe. Sonst soll eben aller 50ms ein Thread erstellt werden.. und im Thread eben aller 100ms i iteriert werden. Das ist ein Test - um das verhalten nach zuschauen. Hat nichts mit der eigentlichen Anwendung zu tun. Sorry, wenn das eben nicht so herüber kam. vG Nancy Zitieren
NancyG Geschrieben 11. Juli 2013 Autor Geschrieben 11. Juli 2013 Ich zumindest würde erst einmal überprüfen, welcher Teil das Thread-Problem verursacht. Das Erstellen des Threads selbst verursacht das Speicher-Leck. Meine Kristallkugel sagt mir, dass es immer problematisch ist, zig Verbindungen zu einer DB aufzubauen (dabei könnte man auch eine Instanz einer Verbindung nutzen). Genauso problematisch ist es, eine Textdatei zig mal zu öffnen und zu schreiben, ohne zu wissen, ob noch andere Prozesse die Datei zum Schreiben geöffnet haben. Mit der TCP-Verbindung ist es genauso, was ist, wenn der Ping (warum auch immer) mal höher als 250ms ist... Also laut meiner Kristallkugel ist das gesamte Vorhaben, so wie es jetzt umgesetzt ist, sowieso kritisch einzustufen. Mutex! Das Verbindungsobjekt, bzw der Stream ist immer offen und wird nur im Thread beschrieben. Mutex WaitOne/ReleaseMutex verhindern dass eben 2 Threads gleichzeitig drauf schreiben. Wie ich oben aber schon sagte - das Problem ist nicht die Geschwindigkeit, die Daten wegzuschreiben. Sondern, dass eben jeder neu erstellte Thread Speicher verbraucht und diesen nicht wieder frei gibt. vG Nancy Zitieren
Klotzkopp Geschrieben 11. Juli 2013 Geschrieben 11. Juli 2013 Ich habe es mit ThreadPoll versucht - und es bleibt das selbe Phänomen. Es starten x Threads, Handels werden erstellt, Speicher wird alloziert. Nach beenden der Threads bleiben die Handles einfach offen - und damit auch der Speicher belegt. Was heißt "nach Beenden der Threads"? Der Threadpool beendet seine Threads gar nicht (zumindest nicht alle). Er lässt sie weiterlaufen, damit er für zukünftige Aufgaben keine neuen starten muss. Das ist ja der Trick an der Sache. Zitieren
Guybrush Threepwood Geschrieben 11. Juli 2013 Geschrieben 11. Juli 2013 Ich werde das Programm so lange laufen lassen, bis der Speicher alle ist - und ich vermute, dass der GC nichts wegräumt - und es zu einer OutOfMemoryException kommt. Was ist denn daraus geworden? Zitieren
NancyG Geschrieben 11. Juli 2013 Autor Geschrieben 11. Juli 2013 Bei 1,8GB RAM hat sich das Programm (ohne DEV-Umgebung) mit der Fehlermeldung "APPCRASH" verabschiedet. Lief bis vorgestern. Ich werde es nochmal im Debugger laufen lassen. Zitieren
lbm1305 Geschrieben 11. Juli 2013 Geschrieben 11. Juli 2013 Bei 1,8GB RAM hat sich das Programm (ohne DEV-Umgebung) mit der Fehlermeldung "APPCRASH" verabschiedet. Lief bis vorgestern. Ich werde es nochmal im Debugger laufen lassen. Das "richtige" Programm, welches Streams und Datenbanken nutzt? Oder das TestProgramm. Was passiert, wenn bei parallel laufen würden? Zitieren
NancyG Geschrieben 11. Juli 2013 Autor Geschrieben 11. Juli 2013 Das *richtige* Programm. Was erhoffst du dir davon, wenn ich beide parallel laufen lasse? vG Nancy Zitieren
Guybrush Threepwood Geschrieben 11. Juli 2013 Geschrieben 11. Juli 2013 Das *richtige* Programm. Wer weiß was das Programm alles macht. Deine Aussage war das wenn du einfach nur Threads startest und wieder beendest der Speicher voll laufen würde und das stimmt nicht. Zitieren
NancyG Geschrieben 11. Juli 2013 Autor Geschrieben 11. Juli 2013 Wieso soll es nicht stimmen. Ich habe die Aussage an Hand von einer Test-App nachvollzogen. Du unterstellst hier einfach Sachen - ohne wahrscheinlich selber den Test gemacht zu haben. Deine Aussage: "Der Speicher wird beim Beenden der App freigegeben", stimmt zwar - aber bringt mir nichts. Und: Was das Programm sonst noch so macht: Genau das, was es soll! Ohne die Threads zu erzeugen - wird kein Speicher verbraten. Aller 250ms bekomme ich ein Callback mit den Daten, die ich dann eben nicht verarbeite. Ja: ich habe auch schon die Threads erstellt, ohne die Daten zu verarbeiten. Selbiges Problem. Sorry, aber ich habe die Frage ja nicht aus langer Weile gestellt, ob jemanden das Phänomen bekannt ist: Das durch erstellen von Threads Speicher verloren geht. vG Nancy Zitieren
Guybrush Threepwood Geschrieben 11. Juli 2013 Geschrieben 11. Juli 2013 Wieso soll es nicht stimmen. Ich habe die Aussage an Hand von einer Test-App nachvollzogen. Du unterstellst hier einfach Sachen - ohne wahrscheinlich selber den Test gemacht zu haben. Weil das Unsinn ist. class Program { static void Main(string[] args) { int i=1; while (true) { Thread t = new Thread(DoSomething); t.Start(); Thread.Sleep(50); Console.WriteLine("{0}", i++); } } static void DoSomething() { Thread.Sleep(100); } } [/PHP] Das kannst du den ganzen Tag lang laufen lassen ohne das dir der Speicher voll läuft oder überhaupt der Speicherverbrauch wächst. Und: Was das Programm sonst noch so macht: Genau das, was es soll! Ohne die Threads zu erzeugen - wird kein Speicher verbraten. Aller 250ms bekomme ich ein Callback mit den Daten, die ich dann eben nicht verarbeite. Ja: ich habe auch schon die Threads erstellt, ohne die Daten zu verarbeiten. Selbiges Problem. Sorry, aber ich habe die Frage ja nicht aus langer Weile gestellt, ob jemanden das Phänomen bekannt ist: Das durch erstellen von Threads Speicher verloren geht. Natürlich liegen deine Probleme nicht daran das du irgendwas falsch machst sondern an einem riesen Fehler in .Net der sonst noch nie jemandem aufgefallen ist... :upps Zitieren
NancyG Geschrieben 11. Juli 2013 Autor Geschrieben 11. Juli 2013 Und auch laufen lassen. Nein, natürlich nicht! Denn sonst hättest du gesehen, dass dein Speicher von ca. 13000Kb innerhalb von einer Minute auf 18000kb anwächst - siehe Bild. Im Bild ist grün eingekreist die offenen Handles - die eben nicht mehr geschlossen werden..... Und wenn ich das den ganzen Tag mache - sehe ich sehr wohl, dass der Speicher zur Neige geht. Sub Main() Dim i As UInt32 = 1 While True Dim t As New Threading.Thread(AddressOf doSomething) t.Start() Threading.Thread.Sleep(50) Console.WriteLine("{0}", i) i += 1 End While End Sub Private Sub doSomething() Threading.Thread.Sleep(100) End Sub Und zumindest ist es bei mir so - und wenn du an dem Code nichts falsches siehst - dann bleibt für mich nur die Erkenntnis: Bei jedem Thread geht Speicher verloren. Wo und wie weiss ich nicht - deswgen farge ich ja hier. Zitieren
Guybrush Threepwood Geschrieben 11. Juli 2013 Geschrieben 11. Juli 2013 Und auch laufen lassen. Nein, natürlich nicht! Denn sonst hättest du gesehen, dass dein Speicher von ca. 13000Kb innerhalb von einer Minute auf 18000kb anwächst - siehe Bild. Im Bild ist grün eingekreist die offenen Handles - die eben nicht mehr geschlossen werden..... Da ich mich zu sehr zusammen reißen muss dir vernünftig zu antworten ist das mein letzter Post hier. Natürlich geht der Speicher erstmal etwas hoch, da der GC wie bereits mehrmals gesagt wurde, nicht sofort hinter dir herräumt weil das viel zu ineffizient wäre. Deshalb geht der Speicherverbrauch erstmal ein paar kb hoch und es werden ein paar hundert Handels geöffnet bevor man im Taskmanager sehen kann wie alles wieder auf den Ursprungszustand zurück geht, oder manchmal auch nur wieder etwas weiter runter geht und dann bei einem späteren Aufräumvorgang wieder ganz runter. Wenn das bei dir in nicht alle paar Sekunden sondern vielleicht nur alle paar Minuten passiert dann liegt das evtl. daran das dein System durch was anderes zu sehr ausgelastet ist, oder vielleicht allgemein schwächer ist. Es bleibt aber dabei der der GC das wieder aufräumt, zumindest in diesem einfachen Beispiel. Wenn etwas wirklich nicht wieder aufgeräumt wird dann liegt das wie auch schon mehrmals gesagt wurde entweder an Designfehlern oder daran das manuell unmanged Resourcen allokiert wurden und nicht wieder freigegeben wurden. Zitieren
SilentDemise Geschrieben 11. Juli 2013 Geschrieben 11. Juli 2013 du hast auch nicht ernsthaft den haken bei visual studio hosting prozess noch gesetzt, oder? Und für die genutzten Ressourcen rufst bzw. implementierst du aber schon IDisposable? Zitieren
Klotzkopp Geschrieben 11. Juli 2013 Geschrieben 11. Juli 2013 Sub Main() Dim i As UInt32 = 1 While True Dim t As New Threading.Thread(AddressOf doSomething) t.Start() Threading.Thread.Sleep(50) Console.WriteLine("{0}", i) i += 1 End While End Sub Private Sub doSomething() Threading.Thread.Sleep(100) End Sub [/code] Dieses Programm steigt bei mir nicht über 2500 K Speicher und 800 Handles. Welches Visual Studio benutzt du, welches .NET-Framework? Zitieren
NancyG Geschrieben 11. Juli 2013 Autor Geschrieben 11. Juli 2013 IDisposable ist überall drin. Ich setze sogar skalare Variable auf Nothing. Welchen Vor/Nachteil hat vsHostProzess? Zitieren
SilentDemise Geschrieben 11. Juli 2013 Geschrieben 11. Juli 2013 im wesentlichen ziehst du damit eine isolierte debugging umgebung hoch. Was bedeutet ist überall drin? implementierst du es ordentlich? Und wird Dispose auch aufgerufen? Rufst du irgendwelchen COM / Win32 Kram auf, der nicht sauber wieder freigegeben wird? Was macht dein Tool überhaupt? Im übrigen: was Klotzkopp sagt. Zitieren
NancyG Geschrieben 11. Juli 2013 Autor Geschrieben 11. Juli 2013 VS2010 Pro, Net 4.0 Bin eben bei 80k offenen Handles, 60Mb. (1h) Und der GC tut nix 20% CPU!? Zitieren
lbm1305 Geschrieben 11. Juli 2013 Geschrieben 11. Juli 2013 Kann man irgendwo den Quellcode des Programms sehen? Es macht einen Unterschied, ob das Programm in eine Datei schreibt oder so tut, als würde es schreiben, bspw. durch ein Thread.Sleep. Zitieren
lbm1305 Geschrieben 11. Juli 2013 Geschrieben 11. Juli 2013 Hier zwei Möglichkeiten, die funktionieren sollten. Sub Main() Dim i As UInt32 = 1 Dim auoResetEvent As AutoResetEvent = New AutoResetEvent(False) While (True) 'Dim task As Task = task.Factory.StartNew(AddressOf DoSomething) 'task.Wait() ' oder ThreadPool.QueueUserWorkItem(AddressOf DoSomething, auoResetEvent) auoResetEvent.WaitOne() Console.WriteLine("Es läuft...{0}", i) i += 1 End While End Sub ' ThreadPool Sub DoSomething(ByVal stateInfo As Object) Console.WriteLine(Thread.CurrentThread.ManagedThreadId) Thread.Sleep(100) CType(stateInfo, AutoResetEvent).Set() End Sub ' Task Sub DoSomething() Console.WriteLine(Thread.CurrentThread.ManagedThreadId) Thread.Sleep(100) End Sub Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.