![]() |
AW: Speicherlecks in fremdem Code/Programm finden
Denke, dass es das Sinnvollste ist, erstmal pro Plugin zu testen. Wenn dann erkennbar ist, dass nur eines (und hoffentlich nicht mehrere) ein Problem verursacht.
Dann kann man anfangen die Quellen durchzusehen, um genauer zu erfahren, wo da was klemmen könnte. Probleme mit Speicherlöschern und dem Zugriff über WMI hatte ich eigentlich bei allen Windowsversionen. Generell würd' ich eine "kontinuierliche" oder aber auch "versionsübergreifende" Fehlermöglichkeit nicht zwingend ausschließen. Deine Bemerkung, dass der Fehler unter W2K nicht auftritt, ist (finde ich) wesentlich. W2K ist wohl die älteste Windowsversion, die Du in Betrieb hast. Daraus schließ ich jetzt erstmal ganz naiv, dass bei der ersten Version von Windows, die nach W2K heraus kam, irgendeine Änderung gemacht wurde, die in den Quellen nicht "nachgezogen" wurde. Oder der Fehler tritt bei der Nutzung einer Funktion auf, die es unter W2K noch nicht gab. |
AW: Speicherlecks in fremdem Code/Programm finden
Zitat:
Deshalb hatte ich vor vielen Jahren eine kleine Änderung eingebaut, die in den Kommentaren auf der alten Homepages des Autors zu finden war, um den Fehler zu beseitigen. Die Änderung bewirkt, dass die Fehlerprüfung in zwei Funktionen (PerfCounterMuninNodePlugin::OpenCounter() und PerfCounterMuninNodePlugin::GetConfig()) anders erfolgt. Wie gesagt ist das nur eine kleine Änderung an einem der Plugins, der restliche Code inkl. aller anderen Plugins blieb davon unberührt. Zitat:
Warten wir mal ab, was die Untersuchung der einzelnen Plugins bringt. Ärgert mich, dass ich diese Idee nicht früher hatte; aber vielleicht hatte ich sie schon, weiß aber das Testergebnis nicht mehr, schließlich schlage ich mich mit dem Problem schon seit Jahren rum... Grüße Dalai |
AW: Speicherlecks in fremdem Code/Programm finden
Zitat:
![]() Normale Objekte verhalten sich so ähnlich wie Delphi-Objekte auch. Rolf |
AW: Speicherlecks in fremdem Code/Programm finden
Zitat:
Delphi-Quellcode:
sollte nach Möglichkeit immer vermieden werden, wenn man C++ Code schreibt (gibt natürlich Ausnahmen).
new
|
AW: Speicherlecks in fremdem Code/Programm finden
Es gibt Neuigkeiten, und zwar gute! Ich habe das Leck schneller als gedacht eingrenzen können: es liegt eindeutig am SpeedFan-Plugin. Ist das Plugin deaktiviert, schwankt der Speicherverbrauch des Munin Node über einige Stunden maximal 12 KB (was ich als normal betrachte). Ist es aktiviert, steigt der Speicherverbrauch zwischen 100 und 800 KB pro 30 Minuten!
Hier mal eine Übersicht der mitgeschriebenen Werte. WS = Working Set, Werte in Kilobyte (KB).
Die Speicherzunahme ist auch auf Win2k zu beobachten. Warum ich hier von einem Unterschied zwischen Win2k und XP+ ausging, ist ganz einfach zu erklären: SpeedFan kam bei mir nie auf Win2k zum Einsatz, sondern erst ab XP; die Systeme mit Win2k benutzten ältere Hardware, die noch mit Motherboard Monitor auslesbar war (daher gab's keinen Grund für SpeedFan). Weitere wichtige Beobachtung: Der Speicherzuwachs ist sogar abhängig davon, wieviele weitere Rechner mit SpeedFan im LAN aktiv sind, d.h. je mehr Systeme desto stärker wächst die Größe des Munin Node! Nun muss nur noch das Leck selbst gefunden werden. Falls jemand Zeit und Lust hat, kann gern einen Blick auf den ![]() Grüße Dalai |
AW: Speicherlecks in fremdem Code/Programm finden
Meine C++-Kenntnisse tendieren gegen 0.
In der von Dir genannten Routine wird in 'ner Schleife mehr oder weniger häufig
Code:
bzw.
currentBlock = new xAPBlockHeader(currentPos);
Code:
aufgerufen. Hier wird ja wohl irgendwas neu erstellt. Was ich nicht finden kann ist die Stelle, an der wieder aufgeräumt wird.
currentBlock = new xAPBlockData(currentPos);
|
AW: Speicherlecks in fremdem Code/Programm finden
Aufgräumt wird später in Zeile 271, aber so wie ich das sehe wird im Block von 239 - 249 unter bestimmten Konditionen das
Delphi-Quellcode:
vergessen.
push_back
|
AW: Speicherlecks in fremdem Code/Programm finden
Zitat:
Zitat:
--- Ich glaube aber, das Leck gefunden zu haben - ich hoffe, ich bin da nicht vorschnell (Test läuft gerade). Im xAP-Protokoll, das SpeedFan da benutzt, wird Broadcasting eingesetzt, d.h. die Pakete aller Rechner kommen auf jedem Munin-Node an. Zusätzlich gibt es wohl Heartbeat-Pakete (Beispiel in ![]() Der Inhalt der Variable blocks wird durch die while-Schleife zusammengebaut, egal, was da für ein Paket reinkommt. Für jeden Abschnitt des Pakets wird mit new ein currentBlock erzeugt, und einzeln an blocks angehängt. In Zeile 267 wird der Inhalt der Variable blocks nur dann an die Klassenvariable m_Blocks weitergegeben, wenn die UID übereinstimmt (und es ein Datenpaket war und kein Heartbeat). Aber was passiert mit dem Inhalt der Variable blocks, wenn das nicht zutrifft, es also das Paket mit einer anderen UID oder ein Heartbeat war? Der dengelt weiter im Speicher rum, ohne zerstört zu werden, denn die Zerstörung passiert nur mit dem Inhalt der Klassenvariable beim nächsten Paket. Das erklärt auch, warum die Zunahme des Speichers mit der Anzahl der mit SpeedFan (mit aktiviertem xAP) laufenden Rechner im LAN ansteigt - mehr Heartbeats, mehr auf dem Heap erzeugte Objekte, die nicht wieder weggeräumt werden. Meine Lösung sieht daher momentan so aus, dass ich in Zeile 276 folgenden Teil zur if-Bedingung aus 267 ergänzt habe:
Code:
um alle Objekte in blocks wieder aufzuräumen. Das sollte alle nötigen Fälle abdecken.
} else {
for (std::vector<xAPBlock *>::iterator it = blocks.begin(); it != blocks.end(); it++) delete *it; } Ob's das wirklich ist (und das einzige Leck), wird sich zeigen. Grüße Dalai |
AW: Speicherlecks in fremdem Code/Programm finden
Trägt zwar nichts zur Problemlösung bei, soll aber verdeutlichen, daß es den Menschen wie den Leuten geht: Wen zur Abwechslung mal interessiert, wie ein sehr schwierig aufzuspürender Softwarefehler wochenlang gesucht, irgendwann gefunden und dann recht einfach beseitigt wurde, der möge
![]() |
AW: Speicherlecks in fremdem Code/Programm finden
Kleiner Nachtrag: Das Speicherleck ist definitiv gestopft. Nach 7,5 Stunden Laufzeit und einer Zunahme des Working Set von nur ca. 40 KB kann ich das guten Gewissens behaupten; diesmal lief es auf einem Win7 x64 mit x64 Prozess, daher ist der Wert nur bedingt vergleichbar mit den vorherigen. Möglicherweise sind noch weitere kleinere Lecks enthalten, aber das kann nur mit einem wesentlich längeren Untersuchungszeitraum ermittelt werden.
Ich habe den Code noch etwas angepasst:
Code:
So wird in jedem Fall aufgeräumt, wenn's nix zu verarbeiten gab. Wahrscheinlich könnte man die boolsche Variable sogar weglassen, weil die Funktion im "guten" Fall sowieso vorher mit return verlassen wird.
size_t SpeedFanNodePlugin::ListenerThread::ProcessBuffer(char *buffer)
{ ... bool clearblocks = false; ... if (headerBlock != NULL) { ... if (headerBlock->uid == uid && headerBlock->xAPClass == "PC.status") { ... } else { clearblocks = true; } } else { clearblocks = true; } if (clearblocks) for (std::vector<xAPBlock *>::iterator it = blocks.begin(); it != blocks.end(); it++) delete *it; ... } Danke an alle Beteiligten! :dp: Grüße Dalai |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:06 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz