Wie oft unterläuft euch ein Memleak?



  • den letzten Memleak hatten wir vor ca. 2 Jahren gefunden. Der Code dazu war mehr als 10 Jahre alt und stammte noch knapp aus der "vor-shared_ptr"-Zeit. Dass das Problem erst nach so langer Zeit hoch kam, lag daran, dass hier nur ca. 20 Bytes allokiert worden sind. Und erst nachdem sich durch äußere Umstände die Aufruffrequenz sehr deutlich gesteigert hat, kam es wirklich nach mehreren Stunden Programmlaufzeit zum 'out of memory'.

    Mal von diesem 'Gruß aus der Vergangenheit' abgesehen, haben wir seit konsequenter Anwendung von RAII - i.A. in Form eines Smart-Pointers - genau NULL Probleme mit Resource Leaks aller Art. Solche Fehler - inklusive des oben erwähnten - sind verdammt schwer zu lokalisieren. Wir hatten in den 90'gern mindestens einen Fall, bei dem wir fast einen Kunden verloren haben. Ursache war ein HANDLE-Leak. Das Problem war dabei gar nicht, dass ein Fehler in der SW war, sondern, dass es so lange dauerte, ihn zu finden - und also zu beseitigen. Das kostet richtig Geld und Reputation.
    Wer heutzutage C++ programmiert ohne RAII arbeitet einfach unprofessionell.

    C++ braucht eben keinen Garbage Collector, weil C++ mit RAII keinen Carbage macht 😉

    Gruß
    Werner



  • Den letzten richtig bösen Leak hatte ich mit einem speziellen, von der Uni gepfleften, Framework. Ein simulierter Joystick, allokierte bei jedem Event Resourcen, welche nicht freigegeben wurden. Das hatte zur Folge dass nach cirka 3 Minuten Joystick-Bewegung das System komplette einfrohr, da ich auf einem Echtzeit-Betriebsystem arbeitete.

    Unter der WinApi habe ich auch ab und zu ein paar Leaks. Aber alle Leaks waren selbst bei exzessiver Nutzung nicht größer als 100 kByte.



  • Keine Memleaks, da keine dynamische Allokation von Speicher.



  • Alle reden hier von RAII, aber auch ohne sollte ein Entwickler in der Lage sein, Memorz Leaks schon beim Programmieren zu vermeiden. Wenn das schon schwer ist, dann liegt einem wohl Programmieren im Allgemeinen nicht.



  • nun, so selten sind die dinger auch wieder nicht 🙄



  • knivil schrieb:

    Alle reden hier von RAII, aber auch ohne sollte ein Entwickler in der Lage sein, Memorz Leaks schon beim Programmieren zu vermeiden. Wenn das schon schwer ist, dann liegt einem wohl Programmieren im Allgemeinen nicht.

    Abgesehen davon, dass die Aussage an sich schon völlig schwachsinnig ist (was heißt in der Lage sein? 10 mal so lange an einem Segment sitzen und dann viel unübersichtlicheren Code haben?), ist es in C++ aufgrund von Exceptions nicht mal theoretisch möglich, ohne RAII Leaks zu vermeiden. Lieber jemanden der RAII vernünftig einsetzen kann, als jemanden der den Code mit deletes zu pflastert.



  • knivil schrieb:

    Alle reden hier von RAII, aber auch ohne sollte ein Entwickler in der Lage sein, Memorz Leaks schon beim Programmieren zu vermeiden.

    Und wie macht man das deiner Meinung nach am besten? 😉



  • knivil schrieb:

    Auf der einen Seite sollen komplexe Maschinen/Prozess/... gesteuert werden und dann schafft man es nichtmal die Anzahl der new/delete ausgeglichen zu halten. Von C++ gut bescherschen kann dann nicht die Rede sein.

    Wer ist "man"?

    knivil schrieb:

    Alle reden hier von RAII, aber auch ohne sollte ein Entwickler in der Lage sein, Memorz Leaks schon beim Programmieren zu vermeiden. Wenn das schon schwer ist, dann liegt einem wohl Programmieren im Allgemeinen nicht.

    Wieso sollte man absichtlich auf RAII verzichten? Um zu zeigen, "wie gut einem Programmieren liegt"?



  • Einfach nur "die Anzahl der new/delete ausgeglichen zu halten" ist kein gutes Rezept, wenn man Memory Leaks vermeiden will...


  • Mod

    cooky451 schrieb:

    ist es in C++ aufgrund von Exceptions nicht mal theoretisch möglich, ohne RAII Leaks zu vermeiden.

    Das was der Compiler da zusammenbaut, sollte man eigentlich auch von Hand nachbauen können. Ist halt unendlich umständlich und man muss bei jeder kleinen Änderung im Code aufpassen, den Abräumcode anzupassen. Daher ist es eine gute Idee, dass man das den Compiler automatisch erledigen lässt.



  • Ohne Wertung: Ohne RAII arbeitet man logischerweise nur bei Code, der auch Exceptions äußerst sparsam einsetzt.



  • SeppJ schrieb:

    cooky451 schrieb:

    ist es in C++ aufgrund von Exceptions nicht mal theoretisch möglich, ohne RAII Leaks zu vermeiden.

    Das was der Compiler da zusammenbaut, sollte man eigentlich auch von Hand nachbauen können. Ist halt unendlich umständlich und man muss bei jeder kleinen Änderung im Code aufpassen, den Abräumcode anzupassen. Daher ist es eine gute Idee, dass man das den Compiler automatisch erledigen lässt.

    Hmja, ein eigenes try/catch um nahezu jeden Funktionsaufruf. Dann sieht's schon fast aus wie Java, fehlt nur noch das finaly. 😃



  • kellerassel schrieb:

    hab grad wieder einen gefunden 😃

    Ausgesprochen selten, wobei mich das das selbst wundert.

    Gelegentlich mit valgrind gegentesten. Allerdings werden inzwischen viele Dinge per TDD entwickelt und valgrind wenn im Test nicht meckert, funktioniert der Rest meistens auch.



  • Bashar schrieb:

    Ohne Wertung: Ohne RAII arbeitet man logischerweise nur bei Code, der auch Exceptions äußerst sparsam einsetzt.

    Naja, ohne RAII ist es überhaupt wohl praktisch unmöglich, tatsächlich dichten Code zu schreiben, wenn Exceptions fliegen. Aber auch in Code, wo garantiert keine Exceptions fliegen, würd ich nicht ohne RAII arbeiten wollen. Selbst eine simple Funktion mit mehr als einem return ist ohne RAII doch schon Mist, sobald sie auch nur eine Datei öffnet oder sonstwas. RAII ist für C++ imo so fundamental, dass ich fast sagen würde: C++ ohne RAII macht keinen Sinn...



  • Nexus schrieb:

    Wieso sollte man absichtlich auf RAII verzichten? Um zu zeigen, "wie gut einem Programmieren liegt"?

    Siehst du irgendwo, wo ich vorschlage, absichtlich auf RAII zu verzichten? Ich nicht. Aber jetzt wird ein C++-Programmierer einfach mal vor C gesetzt. Au scheisse oder wie? Nach meiner Erfahrung ist das nicht selten.

    Wer ist "man"?

    Alle die es nicht koennen. Der Schwellwert liegt bei 5 Stueck.



  • @knivil
    Super-sinnlose Aussage ey.
    Ja, alle reden hier von RAII, weil alle hier von C++ reden.
    Jetzt kommst du mit deinem "aber auch ohne RAII blaaaaaaaaaah", und wenn man dann nachfragt war natürlich nur C gemeint.
    WTF?



  • Wieso ist der Thread dann in "Rund um die Programmierung" und nicht im C++-Unterforum? Und nein, es war nicht C gemeint. Beispiel: C++ auf Mikokontrollern oder in Echtzeitumgebungen oder wo ich mir einfach einen std::vector nicht leisten kann bzw. nicht verfuegbar ist, oder ... . Ja ist vielleicht nur C mit Klassen, dennoch wuerde ich es als C++ ansehen. Aber es ist eben nicht nur Windows + Dektop + Visual Studio und 'ne Tuete Bonbons. Und wer mit new/delete bzw malloc/free nach langer Zeit nicht umgehen kann, sollte eine andere Sprache waehlen, Java beispielsweise. Wo ist das Problem? Alle gleich aufgeschmissen, wenn sie keinen RAII-Code pflegen muessen, von anderen Entwicklern?

    Ich verstehe auch ehrlich nicht, wo das Problem ist, Memory leaks zu finden. Valgrind gibt sie schoen geordnet aus. Fuer Windows gibt es auch massenhafte Tool. Und Ja, man kann auch einen schnell selbst implementieren, sofern nicht allzuviele externe Bibliotheken benutzt erden. Und ja das gilt auch fuer andere Ressourcen.


  • Mod

    knivil schrieb:

    Wieso ist der Thread dann in "Rund um die Programmierung" und nicht im C++-Unterforum? Und nein, es war nicht C gemeint. Beispiel: C++ auf Mikokontrollern oder in Echtzeitumgebungen. Ja ist vielleicht nur C mit Klassen, dennoch wuerde ich als C++ ansehen. Aber es ist eben nicht nur Windows + Dektop + Visual Studio.

    Wenn du Klassen drin hast, dann hast du auch Konstruktoren/Destruktoren und kannst mit RAII programmieren - das wäre ja gerade einer der Hauptnutzen von C++ in solch einer Umgebung.

    Wenn man hingegen C programmiert und trotzdem Probleme mit Memleaks hat, dann muss man sich die Frage gefallen lassen, wieso man dann nicht eine geeignetere Sprache nimmt. Die C++-, Java- und C#-Programmierer hier im Thread scheinen allesamt wenig bis gar keine Probleme zu haben, das liegt sicher nicht daran, dass sie allesamt die Obergurus sind. Java und C# sind natürlich nicht ganz so portabel, aber wo ein C-Compiler existiert, gibt es meistens auch C++.

    knivil schrieb:

    Alle reden hier von RAII, aber auch ohne sollte ein Entwickler in der Lage sein, Memorz Leaks schon beim Programmieren zu vermeiden. Wenn das schon schwer ist, dann liegt einem wohl Programmieren im Allgemeinen nicht.

    RAII/Garbage Collection ist gerade ein Weg, solche Fehler schon beim Programmieren zu vermeiden. Es ist ein sehr einfacher Weg und dazu noch narrensicher. Aber wenn man zusätzlich noch anfinge, selber Ressourcen wieder freizugeben, dann würde das Konzept nicht mehr funktionieren, da man dazu eben diese Mechanismen wieder aushebeln müsste. Eventuell mit zusätzlichen Laufzeitkosten wie bei den C++-Filestreams, wo man die Ressourcen wahlweise automatisch oder von Hand anfordern und freigeben kann und im Destruktor wird dann geprüft, ob noch automatisch aufgeräumt werden muss oder der Programmierer das bereits erledigt hat.



  • Die Welt ist nicht perfekt, weder der Code, den ich ueberantwortet bekomme, noch der, den ich der weitergebe. Memory leaks zu erkennen und zu vermeiden muss jeder in C oder C++ koennen, auch wenn sein Vorgaenger kein RAII benutzt hat oder selbst keins verwendet werden kann, beisielsweise gibt das firmeninterne "Framework" nicht her oder ist Performanceschaedlich.



  • knivil schrieb:

    Die Welt ist nicht perfekt, weder der Code, den ich ueberantwortet bekomme, noch der, den ich der weitergebe. Memory leaks zu erkennen und zu vermeiden muss jeder in C oder C++ koennen, auch wenn sein Vorgaenger kein RAII benutzt hat oder selbst keins verwendet werden kann, beisielsweise gibt das firmeninterne "Framework" nicht her oder ist Performanceschaedlich.

    In dieser nicht so perfekten Welt ist leider auch der Code selbst nicht immer so, dass man jede Möglichkeit, ein Memleak zu erzeugen, sofort sieht und berücksichtigt. Manchmal ist die Welt sogar so wenig perfekt, dass das Argument "dann refaktor doch dass mans sieht" nicht zieht - weil in gewissen Projektkonstellationen Refaktoring einfach extrem teuer wird (Mergeaufwände). Aus dem Grund gibts hier in einer unserer Komponenten eine Art selbstgestrickten Garbage-Collector, der jede Speicheranforderung mitloggt und beim Verlassen der Komponete einfach alles freigibt. Das ist hauptsächlich C-Code, allerdings gibts eine Exceptionklasse, die im Fehlerfall bis an die Grenze der Komponente fliegt - ein ehemaliger longjmp. Leider steht das System dank steigender Verwendung von C++-Klassen auf tönernen Füßen...


Anmelden zum Antworten