Speicherlöcher?



  • Hallo,

    ich arbeite an einem Projekt und versuche herauszufinden, ob ich am Ende Speicherlöcher habe oder nicht. Ich nutze den MS VisualLeakDetector, dem ich bisher immer vertraut habe. Allerdings habe ich nun Langzeittests laufen lassen und folgendes kam heraus:

    Debug-Konfiguration

    Beim Start des Programms zeigt der TaskManager 3,3MB RAM Verbrauch, CPU-Last geht gegen 0%. Nach dem Dauertest zeigt der TaskManager 4,2MB RAM Verbrauch an. Die CPU-Last liegt wieder bei 0%. Zwischenzeitlich "zappelt" RAM-Verbrauch und CPU-Last, was völlig normal ist. Beim Beenden des Programms sagt mir der VLD, dass keine Speicherlöcher festgestellt wurden.

    Release-Konfiguration

    Hier zeigt mein Programm grundlegend das gleich Verhalten, nur mit weniger Speicher (nachvollziehbar).

    Nun mein eigentliches Problem. "Lügt" mich der VLD an, oder macht das Windows-Betriebssystem (vielleicht auch die STL) irgendwas im Hintergrund, dass der Speicherverbrauch mit der Zeit ansteigt? Ich nutze die Threads aus der STL, Smartpointer, sowie Standardcontainer List, Vector und Co. Ich nutze keinerlei sonderbare Konstrukte.

    Kennt jemand dieses Verhalten?

    VG Torsten



  • @TorDev
    Ich denke, das ist normal. Mit deinem Prozess werden div. OS Bibliotheken geladen, die iwas machen. Vllt injiziert sich ein Virenscanner in den Prozess und guckt da auch noch mal nach.



  • @TorDev In diesen Größenordungen finde ich die Anzeige im Task Manager auch nicht sonderlich bemerkenswert. Vor allem nicht, wenn VLD grünes Licht gibt.

    Das, was im Task Manager angezeigt wird, ist letzendlich auch nur der Speicher, der von er malloc-Implementierung vom OS angefordert und in den Addressraum des Prozesses gemappt wurde. Da muss nichtmal wirklich physischer Speicher hinter stecken, solange der nicht aktiv genutzt wird - vielleicht sind das zum Teil auch nur "vorsorgliche" Page-Table-Einträge.

    malloc wird sich da erstens sowieso immer mehr Speicher holen, als von den Heap-Datenstrukturen auch tatsächlich angefordert wurde und sich vermutlich zweitens wegen der Threads auch nicht bei jedem Aufruf und über Zeit immer exakt gleich verhalten, so dass es vielleicht mal ein bisschen weniger anfordert (wenig RAM an Anfang) und mal etwas mehr (steigt nach "Dauertest" an).

    Ich kann mir z.B. gut vorstellen, dass es bei mehreren Threads zwischendurch mal zu "Bursts" kommen kann, wenn z.B. std::vetcor-Vergrösserungen in mehreren Threads gleichzeitig passieren. Da könnte sich malloc vielleicht denken "Ui, das war jetzt sehr viel innerhalb kurzer Zeit, besser etwas mehr anfordern, falls das gleich wieder passiert" 😉 ... wenn es im Schnitt eine Weile dauert, bis es zu einem solchen "Burst" kommt, dann könnte das den leichten Anstieg über Zeit erklären. Ich gehe mal davon aus, dass während des "Dauertests" schon regelmässig Allokationen/Deallokationen in verschiedenen Threads stattfinden, auch wenn sie in Summe nie über einen gewisse Größe gehen, oder?



  • Was Task-Manager per Default anzeigt ist wenn ich mich richtig erinnere "Memory (active private working set)". Das ist ein Wert der nicht geeignet ist Memory-Leaks zu finden und relativ wenig damit zu tun hat wie viel malloc/new man gemacht hat, bzw. wie viel Speicher die malloc/new Implementierung committed hat.

    Das nach meiner Erfahrung beste Tool um Memory Leaks (bzw. allgemein Resource-Leaks) auf Windows zu finden ist Dr.Memory: https://drmemory.org/
    Kann etwas fummelig sein das zum Laufen zu bekommen, aber wenn es läuft, dann ist das Ding 1A.



  • ps: Um die eigentliche Frage zu beantworten: dass Task-Manager in diversen Speicher-bezogenen Spalten höhere Werte nach einem Test anzeigt als direkt nach Start des Programms ist normal.

    Gründe dafür gibt es mehrere. Die IMO wichtigsten sind:

    • Manche Funktionen initialisieren bei der ersten Verwendung diverse Module/Datenstrukturen, wobei Speicher angefordert wird. Der wird dann oft bis zum Beenden des Programms nicht freigegeben. Das betrifft sowohl CRT Funktionen wie auch Win32 Funktionen.
    • Die Heap-Implementierung gibt Speicher nicht sofort an das OS zurück wenn dein Programm delete oder free macht.

    Das ist alles OK und "erwartetes Verhalten" - macht es aber schwer Memory-Leaks anhand des gesamten Speicherverbrauchs des Programms zu ermitteln.

    Also mach dir keine Sorgen was die Werte die Task-Manager anzeigt angeht. So lange es sich da nur um ein paar MB Unterschied handelt, würde ich das ignorieren. Tools wie Dr.Memory oder der von dir verwendete VisualLeakDetector sind viel besser geeignet um Leaks zu finden.

    ps2: Ein gutes komplementäres Tool wäre ASAN:
    https://devblogs.microsoft.com/cppblog/asan-for-windows-x64-and-debug-build-support/
    https://docs.microsoft.com/en-us/cpp/sanitizers/asan?view=msvc-170



  • Vielen Dank für eure Antworten und Hilfe,

    dann gehe ich die Sache mal etwas entspannter an 🙂

    VG Torsten


Log in to reply