Speicherfragmentierung / LFH unter Windows XP



  • Hallo,

    in einer multithreaded-Anwendung steigt der Speicherverbrauch. Da scheinbar keine Speicherlecks nachweisbar sind, liegt es wahrscheinlich an der Speicherfragmentierung. Es werden viele kleine Blöcke allokiert und wieder freigegeben.

    Als Tipp wurde mir gegeben die LFH (Low-Fragmentation Heap) einzuschalten.
    Folgenden Code habe ich direkt am Anfang der Anwendung eingebaut.

    ULONG heapInfo(2);
    BOOL result = HeapSetInformation(heap, HeapCompatibilityInformation, &heapInfo, sizeof heapInfo);
    if (result != TRUE)
        std::cout << "Konnte LFH nicht enablen!" << GetLastError();
    

    Ich bekomme immer den Fehlercode 31 (= A device attached to the system is not functioning) von GetLastError zurück.

    Das dies in der Debug-Version auftritt habe ich verstanden, es tritt bei mir aber auch in der Release-Version auf.

    Wo liegt hier das Problem?

    Gruss
    Lars



  • Das wird zwar wahrscheinlich nicht die Ursache sein, aber du solltest nicht auf result != TRUE (oder result == TRUE ) prüfen.
    Sondern immer auf result == FALSE bzw. result != FALSE .
    Weil BOOL halt ein int ist, und alles ausser 0 ( FALSE ) gilt als "true".

    ----

    Der Code sieht soweit OK aus, k.A. woran das liegt.
    Wo bekommst du denn heap her?



  • Könnte es sein dass es an fehlenden Rechten liegt ? Bei mir gibt auch das MSDN Beispiel zu "HeapSetInformation" ohne admin rechte nen fehler.

    PS: Du weißt dass ab Vista der LFH standardmäßig aktiviert ist ?



  • Du musst den Wert von GetLastError() speichern bevor du ihn ausgibst, da ja auch std::cout einen Betriebssystem-Aufruf tätigen kann der den Wert ändert.

    Ich vermute dann wirst du nen aussagekräftigeren Fehlercode bekommen. 😉



  • Danke für eure Antworten

    @hustbaer: OK, die Überprüfung habe ich geändert. den heap ermittle ich mit GetProcessHeap()

    HANDLE heap = GetProcessHeap();
    ULONG heapInfo(2);
    BOOL result = HeapSetInformation(heap, HeapCompatibilityInformation, &heapInfo, sizeof heapInfo);
    if (result == FALSE)
    {
        DWORD errCode = GetLastError();
        std::cout << "Konnte LFH nicht enablen!" << errCode;
    }
    

    @DarkShadow44: Das mit den Rechten muß ich einmal überprüfen. Ja, das ab Vista LFH aktiv ist, weiss ist. Nur ich bin hier sicher noch 1 Jahr an XP gebunden 😞

    @LFH auch nach dem Zwischenspeichern des Fehlercodes (siehe oben), erhalte ich den Fehlercode 31

    Gruss
    Lars.

    LFH schrieb:

    Du musst den Wert von GetLastError() speichern bevor du ihn ausgibst, da ja auch std::cout einen Betriebssystem-Aufruf tätigen kann der den Wert ändert.

    Ich vermute dann wirst du nen aussagekräftigeren Fehlercode bekommen. 😉



  • BTW: Falls du Visual C++ verwendest, dann wird es nicht reichen beim Process-Heap den LFH einzuschalten, da Visual C++ einen eigenen Heap für die CRT verwendet.
    Wie du an den drankommst um auch dort den LFH einzuschalten kannst du dir ergoogeln - gibt etliche Beispiele (hab den Code jetzt gard nicht zur Hand und auswendig weiss ich es nicht mehr).

    Wie es bei anderen Compilern (z.B. MinGW) aussieht weiss ich nicht, kann leicht sein dass da auch ein eigener Heap verwendet wird.



  • schau dir diesen Beispiel an, vieleicht hilft dir weiter:
    http://www.codeproject.com/Articles/5855/Low-Fragmentation-Heap-and-Function-Interception



  • Hallo

    @hustbaer Auch wenn ich mir das Handle mit _get_heap_handle() hole, tritt wieder der Fehlercode 31 auf.

    HANDLE heap = (HANDLE)get_heap_handle();
    ULONG heapInfo(2);
    BOOL result = HeapSetInformation(heap, HeapCompatibilityInformation, &heapInfo, sizeof heapInfo);
    if (result == FALSE)
    {
        DWORD errCode = GetLastError();
        std::cout << "Konnte LFH nicht enablen!" << errCode;
    }
    

    @Alexey Der Autor schreibt in seinem Kommentar, das er dasselbe macht wie in der Funktion HeapSetInformation. Wie soll es weiterhelfen, da ich auch nicht Detours in mein Projekt integrieren will.

    Gruss
    Lars.

    Alexey schrieb:

    schau dir diesen Beispiel an, vieleicht hilft dir weiter:
    http://www.codeproject.com/Articles/5855/Low-Fragmentation-Heap-and-Function-Interception


Log in to reply