Laden...

Threads

Erstellt von cmpxchg vor 18 Jahren Letzter Beitrag vor 18 Jahren 1.975 Views
C
cmpxchg Themenstarter:in
192 Beiträge seit 2005
vor 18 Jahren
Threads

Hallo,
ich habe folgendes Problem: Ich habe mit einem Memory Profiler festgestellt, dass mein Programm zu viele Threads im Speicher hält.

Prinzipiell starte ich die Thread auf 2 Weisen:


...
public void start()
{
Thread thread = new Thread(new ThreadStart(this.machewas));
thread.Start();
return;  // Hier das return, damit der GC den Thread irgendwann wieder vom Speicher entfernt
}
...

oder so:


...
public void start2()
{
ThreadPool.QueueUserWorkItem(new WaitCallBack(this.machewasandres));
return;
}

Im ersten Fall habe ich dann zu viele Instanzen von class Thread im Speicher und im zweiten Fall zuviele instanzen von WaitCallBack

Zu Testzwecken starte ich alle 500ms einen neuen Thread, der Speicher ist dann in kürzester Zeit voll.

Was kann ich da tun um die Klassen vom Arbeitsspeicher zu entfernen? Ich bin für jede Hilfe dankbar

Danke

6.862 Beiträge seit 2003
vor 18 Jahren

Was meinst du mit zuviele?

Baka wa shinanakya naoranai.

Mein XING Profil.

C
cmpxchg Themenstarter:in
192 Beiträge seit 2005
vor 18 Jahren

zuviele bedeutet ca. 30000 Instanzen, aber es werden immer mehr

S
8.746 Beiträge seit 2005
vor 18 Jahren

Beenden die Threads auch mal wieder?

Ansonsten würd ich mir mal mit einem guten Prozess-Explorer die Zahl der Win32-Threads anschauen.

C
cmpxchg Themenstarter:in
192 Beiträge seit 2005
vor 18 Jahren

Freilich beenden die. Die meisten aufrufe resultieren sofort in ein return

104 Beiträge seit 2006
vor 18 Jahren

Soweit ich weiss müssen die Threads explizit beendet werden, könnte mich aber auch irren.
Und damit du den Thread nicht wieder abschießt bevor er überhaupt wirklich gestartet ist, die while Schleife voher:


while ((thread.ThreadState) != ThreadState.Running)
                    {
                        Thread.Sleep(100);
                    }
if ((thread.ThreadState) == ThreadState.Running)
                     thread.Abort();

Dann sollten deine Threads auch wieder abgeschossen werden 😉

564 Beiträge seit 2006
vor 18 Jahren

Hi!

Der Thread kann sich doch selbst zum Schluss mit thread.abort abschießen, oder!? Eigentlich gehen Threads doch damit zu ende, indem sie an ihr Anweisungsende kommen. Der GC räumt dann beim nächsten Durchlauf alles auf.

der Marcel

EDIT: Da der Garbage Collector sein Tätigkeit asynchron erldedigt, dauert es etwas bis er alles aufräumt. (Laut c't-Experiment ungefähr 1 Minute)

:] 😄Der größte Fehler eines modernen Computers sitzt meist davor 😁 :]

S
8.746 Beiträge seit 2005
vor 18 Jahren

Threads beenden, wenn die Thread-Routine endet. Abort() ist dafür da, einen Thread von einem anderen Thread aus zum Terminieren aufzufordern (diese Aufforderung wird auch nicht in jedem Fall sofort ausgelöst). Abort() ist kein Abschiessen a la Process.Kill sondern eine Bitte (!) an den Thread, doch bitte seine Arbeit einzustellen. Wenn der darauf nicht entsprechend reagiert, gibt es keine Möglichkeit einen Thread zum Beenden zu zwingen.

Das geschilderte Verhalten wird zum einen dem GC geschuldet sein und zum anderen der Tatsache dass .NET-Threads != Win32-Threads. Threads werden vom GC erst abgeräumt, wenn sie auch beendet sind, denn die Runtime hält selbst eine Referenz auf den Thread.

Ansonsten ist die Erzeugung von Threads "teuer" (daher gibts ja auch einen ThreadPool). Ab einer bestimmten Frequenz ist die Erzeugung von Threads kontraproduktiv und reduziert den Durchsatz. Hier muss man dann den Threadpool oder Thread-Sychronisation (händische Thread-Wiederverwendung) einsetzen. Der ThreadPool hat aber den großen Vorteil, dass er je nach Plattform optimal skaliert (Dual-Core oder Multi-Prozessor).

Der GC braucht übrigens für ein Gen0-Bereinigung nur einige Millisekunden.