Heap Fragmentierung



  • Hallo!

    Ich programmiere zwar hauptsächlich in C#, was bedeutet, dass ich mir beim Großteil meiner Arbeit keine Gedanken über Heap Fragmentierung zu machen habe, dennoch bin ich einigermaßen an dem Thema interessiert.
    Welche Arten von C/C++ Programmen sind dabei besonders gefährdet und was kann man machen um Probleme mit der Heap Fragmentierung bei diesen Projekten zu umgehen?



  • Da alle modernen Betriebsysteme Paging vornehmen (Stichwort: virtueller Arbeitsspeicher),
    liegt der vom Programm angeforderte Speicher sowieso im ganzen physikalisch
    vorhanden Arbeitsspeicher verstreut (nur zu sog. "Pages" zusammengefasst).

    Daher hat das Anfordern von Speicher keinen Einfluss auf die Fragmentierung,
    zumindest wenn man nicht zu genau hinschaut.
    Was natürlich passieren kann, ist, dass ein Programm soviel Speicher anfordert,
    dass er gerade nicht in eine Page hineinpasst.

    Dann werden 2 Pages verwendet, wobei von der zweiten dann aber z. B. nur ein
    einzelnes Byte wirklich verwendet wird, der Rest bleibt dann ungenutzt.



  • Das mit dem Paging stimmt schon, aber die Art der Heapfragmentierung ist eine andere Geschichte. Der Heap hat ja auch unabhängig von den bereits allokierten Speicherseiten (ob die fragmentiert sind oder nicht) eine logische Struktur, die aus Speicherblöcken verschiedener Größe besteht. Wenn man in seinem Programm sehr häufig Speicher in unterschiedlichen Größen anfordert und sie in unterschiedlicher Reihenfolge wieder freigibt, entsteht natürlich eine Fragmentierung um dessen Beseitigung sich das Betriebssystem bei unmanaged Code natürlich nicht kümmert und auch nicht kümmern kann. Abhilfe schafft da nur, mit dem Heap behutsam umzugehen und ihn nicht zu sehr zu fordern oder man bedient sich einer Möglichkeit, die das Betriebssystem bietet, zum Beispiel bei Windows das Allokieren mehrerer Heaps für verschiedene Anforderungen oder das Nutzen des Low-Fragmentation-Heaps.



  • Schön langsam wird das ganze etwas durchsichtiger für mich :xmas1: .
    Hast du rein zufällig einen Link wo ich mehr über das Verwenden von mehreren Heaps erfahren kann?
    Apropos Low Fragmentation Heap: Wird der ab WinXP nicht automatisch verwendet?



  • Hier die Links zu den entsprechenden MSDN-Seiten. Der Low Fragmentation Heap ist demnach nur bei expliziter Aktivierung aktiv.

    Memory Management Functions

    Low Fragmentation Heap

    @ anonymus:

    Nochmal zur Sache mit der Fragmentierung - die allokierten Speicherblöcke selbst werden natürlich nicht zerteilt(sie liegen also aus Sicht der Speicheradressierung in einem Stück vor), was du wohl meintest. Die Fragmentierung des Heaps findet also nur zwischen den Speicherblöcken und freiem Speicher statt. Das wirkt sich also nicht wie bei Festplatten durch langsameren Zugriff auf den Speicher aus, sondern dadurch, dass im Extremfall kein Speicher verfügbar ist, wenn man beispielsweise 100MB Speicher anfordert, der zwar vorhanden ist, aber nicht mehr in einem Stück auf dem Heap allokiert werden kann.



  • Ich denke mal alle modernen PC-Betriebssysteme machen paging, aber die embedded Betriebssystem, die ich kenne machen dass nicht.
    Übrigens: der Oberkiller ist sprintf



  • Also schon mal vielen Dank für alles. Zwei Sachen sind mir allerdings noch etwas unklar:
    1. Zur Heap Fragmentierung können nicht nur von mir mit new und malloc() angelegte Objekte, sondern auch z.B. mit mit der WinAPI erstellte HWNDs oder HBITMAPs beitragen - ist das richtig?
    2. Wenn ich Speicher anfordere, der nicht ganz in eine Page passt, müssen trotzdem alle Pages direkt hintereinander im Speicher liegen, was unter gewissen Umständen bedeuten kann, dass auch andere Programme, deren Heap fragmentiert ist, zu Probleme in meinem Programm führen können.



  • 1. Ja, richtig.

    tommazzo schrieb:

    2. Wenn ich Speicher anfordere, der nicht ganz in eine Page passt, müssen trotzdem alle Pages direkt hintereinander im Speicher liegen, was
    unter gewissen Umständen bedeuten kann, dass auch andere Programme, deren Heap fragmentiert ist, zu Probleme in meinem Programm führen können.

    Nein. Du verwechselst Speicherfragmentierung mit Adressraumfragmentierung. Dass der Speicher fragmentiert ist, ist völlig egal, weil sich das Paging darum kümmert. Adressraumfragmentierung ist das, was Probleme macht. Nachdem aber jeder Prozess einen eigenen Adressraum hat, kann da ein anderer nicht reinpfuschen.


Anmelden zum Antworten