Wie weiß ich, wer hält die shared_ptr<>?
Nutze ich boost::shared_ptr in meine Anwendung in C++. Das Speicher problem ist wirklich ernst, und die Anwendung braucht sehr viel Speicher.
Jedoch, weil ich jeden newed Objekt in einen shared_ptr, wenn die Anwendung beendet wird, kein memory-undicht erkannt werden können.
Muss es einige Sache wie std::vector<shared_ptr<> >
pool halten der Ressource. Wie kann ich wissen, wer hält den shared_ptr, beim Debuggen?
Ist es schwer zu überprüfen code Zeile für Zeile. Zu viel code...
Vielen Dank!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Kann man nicht wissen, nur durch das betrachten einer
shared_ptr
, wo die "Geschwister-Zeiger" sind. Sie können testen, ob manunique()
oder Holen Sie sich dieuse_count()
unter andere Methoden.Den beliebten verbreitete Verwendung von shared_ptr wird fast zwangsläufig zu ungewollten und unbemerkten Erinnerung Besatzung.
Zyklische Referenzen sind eine bekannte Ursache, und einige von Ihnen kann werden die indirekten und nur schwer zu erkennen, vor allem in komplexen code, bearbeitet von mehr als einem Programmierer; Programmierer entscheiden kann, als ein Objekt muss eine Referenz auf eine andere als eine schnelle Lösung und haben nicht die Zeit zu prüfen, den code zu sehen, wenn er schließt einen Zyklus. Diese Gefahr wird Massiv unterschätzt.
Weniger gut verstanden ist, ist das problem der unveröffentlichten Referenzen. Wenn ein Objekt freigegeben ist, um viele shared_ptrs dann wird es nicht zerstört werden, bis jeder von Ihnen auf "null" gesetzt oder den Bereich verlässt. Es ist sehr leicht zu übersehen, eine dieser Referenzen und Objekte lauern ungesehen in Erinnerung, dass Sie dachte, Sie sei fertig mit.
Zwar streng genommen sind diese keine memory-leaks (es wird alles freigegeben, bevor das Programm beendet wird), sind Sie genauso schädlich und schwieriger zu erkennen.
Diese Probleme sind die Folgen, zweckmässig, falschen Erklärungen:
1. Das deklarieren, was Sie wirklich wollen, um einzelnen das Eigentum als shared_ptr. scoped_ptr wäre korrekt, aber dann ist jede weitere Referenz auf das Objekt wird ein raw-pointer, der könnte Links hängen.
2. Das deklarieren, was Sie wirklich wollen, um eine passive Beobachtung der Referenz als shared_ptr. weak_ptr wäre korrekt, aber dann haben Sie den Aufwand der Konvertierung zu share_ptr jedes mal, wenn Sie es verwenden möchten.
Ich vermute, dass Ihr Projekt ist ein gutes Beispiel für die Art von Schwierigkeiten, die diese Praxis kann dir in.
Wenn Sie einen Speicher-intensive Anwendung, die Sie wirklich brauchen, einzigen Besitz, so dass Ihr Entwurf ausdrücklich control-Objekt-Lebenszeiten.
Mit Einzel-Eigentum opObject=NULL; wird auf jeden Fall löschen Sie das Objekt und Sie wird es jetzt tun.
Mit gemeinsamen Eigentum spObject=NULL; ........wer weiß?......
Einer Lösung zu baumeln oder kreisförmigen smart-pointer-Referenzen, die wir gemacht haben ist, passen Sie die smart-pointer-Klasse hinzufügen, um eine debug-nur Buchhaltung Funktion. Wenn ein smartpointer fügt eine Referenz auf ein Objekt, nimmt es einen stack-trace und stellt Sie in einer Karte, deren jeder Eintrag verfolgt
Wenn ein smartpointer geht out of scope, dessen Eintrag in der Landkarte gelöscht wird. Wenn der Letzte smartpointer, um ein Objekt zerstört wird, wird die pointee-Objekt bekommt einen Eintrag in der map entfernt.
Dann haben wir eine "track-leaks" - Befehl mit zwei Funktionen: '[re]start-Leck-tracking " (das löscht die gesamte Karte und aktiviert das tracking, wenn es nicht bereits), und 'drucken öffnen Referenzen" zeigt alle ausstehenden smartpointer Referenzen erstellt, da die "start-Leck-tracking" - Befehl ausgegeben wurde. Da können Sie sehen, der stack-traces, wo diese smart-Pointer entstanden ist, können Sie ganz einfach genau wissen, wer Sie hat aus Ihrem Objekt freigegeben wird. Es verlangsamt Dinge nach unten, wenn seine auf, so dass wir nicht lassen Sie es die ganze Zeit.
Es ist eine ganze Menge Arbeit zu implementieren, aber auf jeden Fall Wert wenn Sie haben eine Codebasis, in denen dies geschieht, eine Menge.
Möglicherweise ein shared pointer memory-leak über Zyklen. Was passiert, ist Ihre gemeinsame Objekte können Verweise auf andere freigegebene Objekte, die schließlich führen Sie zum original zurück. Wenn dies passiert wird der Zyklus hält alle Referenzzähler auf 1, obwohl niemand sonst kann den Zugriff auf die Objekte. Die Lösung ist schwache Zeiger.
std::weak_ptr
.shared_ptr
. Wenn Sie ersetzen eineshared_ptr
mit einemweak_ptr
Sie nicht mehr einen Zyklus von starken Referenzen, IOW: Sie haben nicht einen Zyklus besitzen, smart-Pointer mehr. Sie haben "gelöst" zu den zyklischen ownership-problem durch die Unterdrückung der zyklischen Eigentum. Wenn die "Lösung" akzeptabel ist, bedeutet es, dass Sie eigentlich nie gebraucht semantische zyklisches Eigentum.weak_ptr
ist nicht magic.Versuchen refactoring einige Ihren code so, dass das Eigentum ist mehr explizit ausgedrückt, die durch die Nutzung der weak-Pointer statt der shared Pointer an einigen stellen.
Wenn man sich die Klasse Hierarchie ist es möglich, zu bestimmen, welche Klasse wirklich halten sollte, ein shared pointer und die lediglich muss nur die schwachen ein, so können Sie vermeiden, Zyklen, wenn es irgendwelche gibt, und wenn die "echte" Eigentümer-Objekt ist zerstört, "nicht-Besitzer" Objekte sollte bereits verschwunden. Wenn es sich herausstellt, dass einige Objekte verlieren, Zeiger zu früh ist, sehen Sie in Objekt-Zerstörung-Sequenz in Ihre app und zu beheben.
weak_ptr
scheinen zu implizieren, dass es ist ein debugging-tool, aber Sie sagen nicht ganz klar. Bemerkung: das ist weniger effizient als mit einem normalen C++ - Zeiger: vielleicht brauchen wir einchecked_ptr
kann definiert werden alsweak_ptr
oder als "normaler" pointer " smart pointer.Du bist offensichtlich holding auf Verweise auf Objekte innerhalb der Anwendung. Dies bedeutet, dass Sie sind, auf den Zweck, Sie halten die Dinge in Erinnerung. Das bedeutet, dass Sie don ' T haben ein memory leak. Ein Speicherleck ist wenn Speicher reserviert, und dann halten Sie nicht, einen Verweis auf die Adresse.
Im Grunde, Sie müssen sich auf Ihr design und herauszufinden, warum Sie halten so viele Objekte und Daten im Speicher, und wie kann man Sie minimieren.
Die eine Möglichkeit, dass Sie eine pseudo-memory leak ist, dass Sie schaffen mehr Objekte, als Sie denken, Sie sind. Versuchen Sie Haltepunkte auf alle Anweisungen, die mit einem "neuen". Sehen Sie, wenn Ihre Anwendung ist Bau mehr Objekte als Sie dachte, es sollte, und dann Lesen, dass code.
Das problem ist wirklich nicht so viel ein Speicher-Leck, wie es ist ein Problem Ihrer Anwendung design.
remove
ist für jedenadd
nur alsdelete
ist für jedennew
. Genau den gleichen Fehler bei der Programmierung, verursacht genau das gleiche problem. Eine "Ressource" ist ein eigentlich nur ein paar der Funktionen, die aufgerufen werden, eine gleiche Anzahl von Zeiten mit den entsprechenden Argumenten und der "resource-leak" ist das, was passiert, wenn Sie es versäumen, das zu tun.Ich würde vorschlagen, die Verwendung von UMDH wenn Sie auf windows. Es ist ein sehr mächtiges Werkzeug. Verwenden Sie es finden Zuordnungen pro Transaktion/Zeit-Zeit, die Sie erwarten, befreit zu werden, dann finden wer hält Sie.
Weitere Informationen gibt es auf diese SO beantworten
Der Speicher-Lecks, verursacht durch smart pointers
Ist es nicht möglich zu sagen, welche Objekte eigenen shared_ptr aus dem Programm. Wenn Sie unter Linux einen sicheren Weg, um das Debuggen der Speicher-Lecks ist die Valgrind - Werkzeug -- es wird zwar nicht direkt Ihre Frage zu beantworten, es wird Ihnen sagen, wo der Speicher reserviert wurde, das ist in der Regel ausreichend für die Lösung des Problems. Ich vorstellen, Windows hat vergleichbare tools, aber ich weiß nicht welche am besten ist.