Einzelnen Beitrag anzeigen

Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.682 Beiträge
 
Delphi 5 Professional
 
#18

AW: Speicherlecks in fremdem Code/Programm finden

  Alt 8. Jan 2017, 16:18
Aufgräumt wird später in Zeile 271 [...]
So ist es.

Zitat:
[...] aber so wie ich das sehe wird im Block von 239 - 249 unter bestimmten Konditionen das push_back vergessen.
Nein. Man muss hier leider ein bisschen um die Ecke denken. Der Header wird erst beim folgenden Schleifendurchlauf in die Variable blocks aufgenommen. Der letzte Datenblock folgt dann durch das push_back() nach der while-Schleife.

---

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 example2.txt), die anzeigen "ich lebe noch".

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:
} else {
    for (std::vector<xAPBlock *>::iterator it = blocks.begin(); it != blocks.end(); it++)
      delete *it;
}
um alle Objekte in blocks wieder aufzuräumen. Das sollte alle nötigen Fälle abdecken.

Ob's das wirklich ist (und das einzige Leck), wird sich zeigen.

Grüße
Dalai

Geändert von Dalai ( 8. Jan 2017 um 16:21 Uhr)
  Mit Zitat antworten Zitat