Hab keine Angst, sieh zu, wie es wächst

In diesem Beitrag werde ich über meine Missgeschicke mit shared_ptr Smart Pointern sprechen. Nachdem ich die Next-Level-Generation in meinem Spiel Death-Mask implementiert hatte, bemerkte ich eine Erinnerung Leck . Jede neue Stufe erhöhte den verbrauchten RAM um + 1 Megabyte. Es ist offensichtlich, dass einige Objekte im Speicher verblieben und nicht freigegeben wurden. Um diesen Umstand zu korrigieren, war es notwendig, die korrekte Implementierung von Ressourcen bei Überlastung des Levels zu implementieren, was offenbar nicht geschehen ist. Da ich intelligente Zeiger verwendet habe, gab es mehrere Möglichkeiten, dieses Problem zu lösen. Die erste bestand darin, den Code manuell zu überprüfen (lang und langweilig), während die zweite darin bestand, die Fähigkeiten des lldb-Debuggers und des libstdc++-Quellcodes auf die Möglichkeit einer automatischen Nachverfolgung zu untersuchen Zähleränderungen.

Im Internet liefen alle Ratschläge darauf hinaus, den Code manuell zu überprüfen, ihn zu reparieren und sich selbst mit Peitschenhieben zu schlagen, nachdem man die problematische Codezeile gefunden hatte. Es wurde auch vorgeschlagen, ein eigenes System für die Arbeit mit dem Speicher zu implementieren, wie es alle großen Projekte tun, die seit den 90er und 2000er Jahren entwickelt wurden, bevor intelligente Zeiger im C++11-Standard eingeführt wurden. Ich habe versucht, Haltepunkte im Konstruktor einer Kopie aller shared_ptrs zu verwenden, aber nach mehreren Tagen passierte nichts Nützliches. Es gab die Idee, Protokollierung zur libstdc++-Bibliothek hinzuzufügen, aber der Arbeitsaufwand erwies sich als enorm.


Cowboy Bebop (1998)

Die Lösung kam mir plötzlich in Form der Verfolgung von Änderungen in der privaten Variablen shared_ptr – use_count. Dies kann mithilfe von in lldb integrierten Watchpoints erfolgen. Nach dem Erstellen eines shared_ptr über make_shared können Änderungen am Zähler in lldb mithilfe der Zeile:
verfolgt werden

watch set var camera._M_refcount._M_pi->_M_use_count

Wo “Kamera” Dies ist ein shared_ptr-Objekt, dessen Zählerstand verfolgt werden muss. Natürlich variieren die Interna von shared_ptr je nach Version von libstdc++, aber das allgemeine Prinzip ist verständlich. Nach der Installation des Watchpoints starten wir die Anwendungen und lesen den Stacktrace jeder Zähleränderung, dann schauen wir uns den Code an (sic!), finden das Problem und beheben es. In meinem Fall wurden Objekte nicht aus Cache-Tabellen und Spiellogiktabellen befreit. Ich hoffe, dass diese Methode Ihnen beim Umgang mit Lecks bei der Arbeit mit shared_ptr hilft, und ich liebe dieses Speichertool noch mehr. Viel Spaß beim Debuggen.

Leave a Comment

Your email address will not be published. Required fields are marked *