2012-08-30 7 views
7

Ich habe ein Programm, das Daten von einem Socket akzeptiert, einige Qualitätskontrolle und verschiedene andere Konditionierung zu ihm, dann schreibt es in eine Named Pipe. Ich habe Valgrind darauf ausgeführt und alle Speicherlecks repariert, die ursprünglich existierten. Ich habe dann eine 'Demo' -Umgebung auf einem System erstellt, auf dem ich 32 Instanzen dieses Programms ausgeführt habe, von denen jedes einzelne Daten gespeist und jedes an seine eigene Pipe ausgegeben wurde. Wir haben es getestet und alles sah gut aus. Dann versuchte ich es mit Stress zu testen, indem ich die Geschwindigkeit erhöhte, mit der Daten auf eine absurde Rate geschickt wurden, und die Dinge sahen zunächst gut aus ... aber meine Programme verbrauchten immer mehr Speicher, bis ich keine Ressourcen mehr hatte.wie Speicherleck zu jagen Valgrind sagt nicht existiert?

Ich wandte mich an Valgrind und führte das gleiche Setup außer mit jedem Programm in Valgrind mit Leck-Check = voll ausgeführt. Ein paar seltsame Dinge sind passiert. Erstens, der Speicher ist undicht, aber nur bis zu dem Punkt, wo jedes Programm .9% meines Gedächtnisses verbraucht hatte (vorher hatte das größte Gedächtnisschwein volle 6% meines Gedächtnisses). Mit Valgrind laufen die CPU-Kosten der Programme hoch und ich war jetzt bei 100% CPU mit einem riesigen Last-Durchschnitt, also ist es möglich, dass der Mangel an verfügbarer CPU dazu führte, dass die Programme langsam genug liefen, dass das Leck zu lange dauerte . Als ich versuchte, diese Programme zu stoppen, zeigte Valgrind keine direkten Speicherlecks, es zeigte einige potentielle Speicherlecks, aber ich überprüfte sie und ich denke nicht, dass irgendwelche von ihnen echte Speicherlecks darstellen; und außerdem zeigte das mögliche Speicherleck nur einige Kilobyte, während das Programm mehr als 100 MB benötigte. Der erreichbare (nicht ausgelaufene) Speicher, der von valgrind gemeldet wurde, befand sich ebenfalls im KB-Bereich. Valgrind scheint also zu glauben, dass meine Programme nur einen Bruchteil des Speichers verbrauchen, den Top angibt.

Ich habe ein paar andere Tests durchgeführt und bekam seltsame Ergebnisse. Ein einziges Programm, sogar mit der dreifachen Rate, bei der mein ursprüngliches Speicherleck erkannt wurde, scheint nie mehr als 0,9% Speicher zu verbrauchen, zwei Programme verlieren bis zu 1,9 bzw. 1,3% Speicher, aber nicht mehr usw., es ist als ob die Menge des ausgelaufenen Speichers und die Rate, mit der es leckt, hängt irgendwie davon ab, wie viele Instanzen meines Programms gleichzeitig laufen; was keinen Sinn ergibt, sollte jede Instanz 100% unabhängig von den anderen sein.

Ich habe auch gefunden, wenn ich 32 Instanzen mit nur einer Instanz läuft in Valgrind läuft die valgrinded-Instanz (das ist ein Wort, wenn ich sage!) Speicher verliert, aber mit einer geringeren Geschwindigkeit als die außerhalb von Valgrind. Die Valgrind-Instanz wird immer noch sagen, dass ich keine direkten Lecks habe und weit weniger Speicherverbrauch meldet als Top.

Ich bin eher ratlos, was dieses Ergebnis verursachen könnte, und warum Valgrind sich weigert, den Speicherverlust zu kennen. Ich dachte, es könnte eine externe Bibliothek sein, aber ich benutze keine externen Bibliotheken. nur grundlegende C++ Funktionen/Objekte. Ich dachte auch, es könnten die Daten sein, die in die Ausgangsleitung geschrieben werden, um den Puffer unbegrenzt wachsen zu lassen, aber 1) sollte ein oberer Grenzwert sein, dass ein solcher Puffer wachsen kann und 2) sobald Speicher verloren gegangen ist, wenn ich die Daten ablege Input-Rate zu nichts der Speicher bleibt konsumiert, anstatt langsam auf einen angemessenen Betrag zurückzufallen.

Kann mir jemand einen Hinweis geben, wo ich von hier aus schauen soll? Ich bin total ratlos, warum sich die Erinnerung so verhält.

Danke.

+2

Sind Sie sicher, es ist ein Leck, und nicht nur ein Teil Ihrer Programmierung Speicher sammeln? Hast du das Massiv ausprobiert? – PlasmaHH

+0

Ich habe selbst ähnliche Probleme (obwohl nicht so skurril) und ich bin sehr an Feedback interessiert. Ein Vorschlag: Könnten Sie das Betriebssystem/die Version, die Sie verwenden, klären? Ich nehme an, es ist ein Linux-Dist. –

+0

Valgrind führt Ihr Programm in einer Sandbox aus und macht eine große Menge an Verarbeitung. Sie sollten erwarten, dass es eine viel höhere CPU-Auslastung und eine wesentlich geringere Leistung als die gleiche Anwendung hat, die nicht mehr über Valgrind läuft. Ich würde darüber nachdenken, ob das Programm während des Stresstests zusätzliche Puffer erstellt, um Daten zu speichern, die nicht in die Pipe gelangen können und die anwachsen (nicht durchgesickert, sondern nur wachsen, weil Sie das Tempo nicht halten können). –

Antwort

1

Das klingt wie ein Problem, das ich kürzlich hatte.

Wenn Ihr Programm Daten akzeptiert und intern ohne Begrenzung zwischenspeichert, kann es schneller lesen und puffern, als es die Daten ausgeben kann. In diesem Fall wird die Speicherbelegung weiterhin unbegrenzt zunehmen.

Je mehr Instanzen des Programms ausgeführt werden, desto langsamer wird jede Instanz und desto schneller werden die Puffer erhöht.

Dies kann oder kann nicht Ihr Problem sein, aber ohne weitere Informationen ist es das Beste, was ich tun kann.

+0

Dies war am nächsten zu genau. Ich sollte Daten alle x Sekunden ausgeben (confugred von einer Konfigurationsdatei). Aber aufgrund eines Fehlers stieg der Zähler, der meine Timeout-Zeit gespeichert hatte, beim Start inkrementiert, also speicherte ich eine Minute + Daten. Eine zusätzliche Systembelastung führte dazu, dass der Fehler, mit dem mein Timeout-Zähler inkrementiert wurde, beim Start häufiger auftrat. Ich möchte Plasma für die Erwähnung eines Massivs danken, das mich in die richtige Richtung gebracht hat. Ich dachte, memcheck würde mir sagen, dass nicht viel Speicher verwendet wird, also habe ich mir den internen Speicher nicht angesehen; Ich habe anscheinend memcheck falsch gelesen. – dsollen

2

Sie sollten zuerst nach einem weichen Leck suchen. Es passiert, wenn ein statisches oder Singleton schrittweise einen Puffer oder einen Container vergrößert und Müll darin sammelt. Technisch ist es kein Leck, aber seine Auswirkungen sind genauso schlecht.

1

Darf ich vorschlagen, dass Sie es mit MemoryScape versuchen? Dieses Tool leistet einen guten Job bei der Erkennung von Speicherlecks. Es ist nicht kostenlos, aber angesichts der aufgewendeten Zeit und Energie ist es einen Versuch wert.

Verwandte Themen