Laden...

Speichermanagement

Erstellt von klaus1 vor 18 Jahren Letzter Beitrag vor 18 Jahren 2.206 Views
klaus1 Themenstarter:in
180 Beiträge seit 2005
vor 18 Jahren
Speichermanagement

Hallo!

Habe mittlerweile ein ziemlich großes Programm, mit sehr viel Umfang geschrieben, auch mit NationalInstruments Eingabekarte..
Mein Problem: nach ca. 50 Messungen, bzw. Abläufen, wächst der Speicher so stark an, dass ich beim Stoppen von diversen Sachen 100% CPU erreiche, und das System für 5 sec. auf 100% läuft, erst dann lässt sich das ganze wieder steuern.

Wie kann ich Speicher wieder freigeben? Insbesondere ab 50 000k im Taskmanager wirds kritisch!

Meine Frage: Kann ich im Visual Studio irgendwie erstellte Objekte (mit new) die ich nicht mehr benötige per Hand freigeben, insbesondere statt auf den Garbage Collector zu warten, der ja zugreift wie’s grad reinpasst!
Hab was gefunden mit .Dispose(), allerdings kann ich das nur bei manchen Variablen verwenden.

Wichtig wäre das Auffinden von nicht mehr benötigten Variablen!
LG, Klaus

4.506 Beiträge seit 2004
vor 18 Jahren

Hallo klaus1!

Herzlichen Glückwunsch!

Du hast eben eine große Schwachstelle von .NET entdeckt 🙂

Es ist überhaupt nicht möglich nicht mehr zu brauchende Objekte zerstören zu lassen, das macht ausschließlich der Garbage Collector! Auch .Dispose() bewirkt keine direkte Zerstörung, sondern nur eine direkte Markierung "zum zerstören freigegeben".

Eine Möglichkeit zur Beschleunigung von Zerstören der Objekte gibt es:

die Referenz auf Objekte auf null setzen, und danach GC.Collect() aufrufen.

Das soll angeblich den Müll forciert aufräumen, doch auch darauf ist kein 100%iger Verlass!

Aber besser geht´s nicht!

Deshalb ist auch in den heutigen Zeiten von Arbeitsspeicherüberfluß noch eine Speicherminimale Programmierung vonnöten. Also nur das in Anspruch nehmen, was zwingend notwendig (vielleicht öfter mit Singleton-Pattern, oder gleich nach der Benutzung wieder die referenz löschen...)

Ciao
Norman-Timo

A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”

K
35 Beiträge seit 2005
vor 18 Jahren

Hi,

dumme zwischen Frage: Ist da für .Net 2.0 Besserung in Sicht?

mfg Kl1mm

Leben bedeutet lernen, leben bedeutet Veränderung... :]

M
456 Beiträge seit 2004
vor 18 Jahren

Für mich hört sich das eher nach "unschön programmiert" an. Wenn der Speicher so stark anwächst und du 100% CPU Auslastung hast, dann machst du irgendwas verkehrt. (Du liest doch nur Messwerte aus, oder?)

I am Jack's smirking revenge.
I am Jack's raging bile duct.
I am Jack's cold sweat.
I am Jack's complete lack of surprise.
I am Jack's broken heart.
I am Jack's wasted life.

1.373 Beiträge seit 2004
vor 18 Jahren

Da schließe ich mich maxE an. Bei "ordentlicher" Programmierung ist der GC kaum zu spüren.

Zunächst solltest du einmal feststellen, ob es überhaupt der GC ist, der die Auslastung verursacht. Hilfreiche Tools hierfür sind der CLR Profiler 2.0 sowie die Leistungskonsole (Systemsteuerung->Verwaltun->Leistung). Bei ersterem kannst du u.a. sehen, wann der GC aktiviert wird, wieviel Speicher womit gefüllt ist und wie lange welche Methode benötigt. Bei der Leistungskonsole kannst du verschiedene Indikatoren testen, z.B. die Anzahl der Collections (dümmlicherweise mit "Auflistungsanzahl der Generation 0/1/2" bezeichnet) oder die GC-Zeitdauer in Prozent. Beide Indikatoren findest du beim Datenobjekt .NET CLR Speicher.

Als eine "große Schwachtstelle von .NET" würde ich persönlich den GC nicht bezeichnen. Wie gesagt, richtig programmiert ergeben sich durch ihn keine wirklichen Nachteile. Im Gegenteil: die Speicherverwaltung von .NET beitet diverse Vorteile - u.a. weniger Leaks und schnellere Heapallokationen.

Dispose() markiert übrigens ein Objekt nicht als "bereit zum freigeben". Dispose() ist in der Regel so implementiert, dass nicht-verwaltete Resourcen (z.B. offene Dateien, nicht-verwalteter Speicher) direkt oder indirekt freigegeben werden. Bei Objekten, die einen Finalizer implementieren ruft Dispose i.d.R. den Aufräumcode direkt auf und veranlasst den GC, den Finalizer nicht mehr aufzurufen, was eine schnellere Freigabe des Objekts ermöglicht. Stichwort: Dispose-Pattern.

MfG VizOne

1.985 Beiträge seit 2004
vor 18 Jahren

Hallo,

wo wir jetzt schon bei der Sache sind, habe ich noch eine Frage dazu. Habt ihr mal ein Beispiel für "richtig programmieren", was die Speicherauslastung anbelangt? Das man nicht in einer Schleiffe n Objekte mit new neu anlegen sollte, sondern, sofern es möglich ist, die Daten eines Objektes ständig ändert, ist eigentlich klar, aber wie sollte man sonst vorgehen?

Ist es zum Beispiel sinnvoll, dass so zu machen?


Class myClass = new Class();

// Nette Sachen mit dem Objekt machen.
// ...

// Und zum Schluss Objekt auf null setzen.
myClass = null;

Ist das sinnvoll und/oder habt ihr evtl. noch mehr hilfreiche Tipps?

Gruß,
Fabian

"Eine wirklich gute Idee erkennt man daran, dass ihre Verwirklichung von vornherein ausgeschlossen erscheint." (Albert Einstein)

Gefangen im magischen Viereck zwischen studieren, schreiben, lehren und Ideen umsetzen…

Blog: www.fabiandeitelhoff.de

1.373 Beiträge seit 2004
vor 18 Jahren

Für dieses Szenario ist das myClass = null vollkommen sinnlos. Der JITter kann das Objekt bereits viel früher als entfernbar einstufen und myClass = null vollkommen ignorieren. Bei Member- und statischen Variablen sieht es etwas anders aus. Solange das Objekt/der Typ selbst erreichbar ist, sind auch dessen Member erreichbar. Wenn man diese frühzeitig auf null setzt, können sie bereits entfernt werden, während das Elternobjekt noch existiert.

Siehe
http://blogs.gotdotnet.com/cbrumme/permalink.aspx/e55664b4-6471-48b9-b360-f0fa27ab6cc0
http://msdn.microsoft.com/msdnmag/issues/1100/gci/
http://msdn.microsoft.com/msdnmag/issues/1200/gci2/

MfG VizOne

1.985 Beiträge seit 2004
vor 18 Jahren

Hallo VizOne,

vielen Dank für die Erklärungen und die Links.

Gruß,
Fabian

"Eine wirklich gute Idee erkennt man daran, dass ihre Verwirklichung von vornherein ausgeschlossen erscheint." (Albert Einstein)

Gefangen im magischen Viereck zwischen studieren, schreiben, lehren und Ideen umsetzen…

Blog: www.fabiandeitelhoff.de

klaus1 Themenstarter:in
180 Beiträge seit 2005
vor 18 Jahren

Habe folgendes Problem, dass ich ziemlich oft während meiner Messung, und einlesen der Messdaten, sehr viele Threads starte und stoppe!

Ich denke mein Problem liegt am stoppen der Threads!
Ich verlasse nur die große while schleife im Thread! der Compiler im Debug modus schreibt zwar: Thread beendet, aber gibt er auch wirklich speicher frei?
muss ich mich darum selber kümmern?
Bitte um Hilfe!
LG, Klaus