Zum Inhalt springen

Dynamischer Speicher

aus Wikipedia, der freien Enzyklopädie
Dies ist eine alte Version dieser Seite, zuletzt bearbeitet am 24. Juni 2005 um 08:34 Uhr durch 195.253.12.52 (Diskussion). Sie kann sich erheblich von der aktuellen Version unterscheiden.

Der dynamische Speicher, auch Heap (engl. für Halde, Haufen) oder Freispeicher ist ein Speicherbereich, aus dem zur Laufzeit eines Programmes zusammenhängende Speicherabschnitte angefordert und in beliebiger Reihenfolge wieder freigegeben werden können. Die Freigabe kann sowohl manuell als auch mit Hilfe einer automatischen Speicherbereinigung erfolgen. Eine Speicheranforderung vom Heap bzw. Freispeicher wird auch dynamische Speicheranforderung genannt.

Der Unterschied zum Stack (Stapel- oder Kellerspeicher) besteht darin, dass beim Stack angeforderte Speicherabschnitte in der umgekehrten Reihenfolge wieder freigegeben werden müssen, in der sie angefordert wurden. Beim Stack spricht man auch von automatischer Speicheranforderung. Die Laufzeitkosten einer automatischen Speicheranforderung sind in der Regel deutlich geringer als die bei der dynamischen Speicheranforderung. Allerdings ist bei intensiver Nutzung durch sehr große oder sehr viele Anforderungen der für den Stack reservierte Speicher bald aufgebraucht - dann droht ein Programmabbbruch wegen Stack-Overflow.


Unterstützung von dynamischen Speicheranforderungen in Programmiersprachen

Programmiersprachen unterstützen die dynamische Speicheranforderung auf unterschiedliche Weisen. In ISO-C gibt es dafür beispielsweise die Funktionen malloc() und realloc(). Mit der Funktion free() wird der Speicher dann wieder freigegeben.

In ISO-C++ gibt es außer den bereits von C übernommenen Funktionen die Möglichkeit, Speicher dynamisch mit Hilfe von new anzufordern bzw. mit delete wieder freizugeben. In C++ wird manchmal zwischen Heap und Freispeicher unterschieden. Dabei stellen Heap und Freispeicher - zumindest konzeptionell - unterschiedliche Speicherbereiche dar. Mittels malloc(), realloc() oder free() wird dabei auf den Heap zugegriffen, mittels new und delete auf den Freispeicher.

Speicherverwaltung

Im Gegensatz zum Stack ist die Verwaltung des Heaps durch die Laufzeitumgebung etwas komplizierter, da das Anfordern und Freigeben von Speicherabschnitten völlig dynamisch und unvorhersehbar erfolgen kann. An die dynamische Speicherverwaltung werden die folgenden, einander teilweise widersprechenden Anforderungen gestellt:

Da Programme Speicherbereiche in unterschiedlichen Größen anfordern können, muss auch die Heap-Verwaltung Blöcke unterschiedlicher Größe bereit halten, da es Verschwendung wäre, z.B. einen Block mit 10 KiloByte zu reservieren, wenn das Programm gerade mal 100 Byte benötigt (best-fit Strategie).

Falls Blöcke auch geteilt werden können, kann es aber umgekehrt auch wieder sinnvoll sein, einen Block mit möglichst großem "Rest" zu reservieren (worst-fit Strategie). Die Überlegung ist, dass ein Bereich mit 900 Byte eher noch wo anders verwendet werden kann als ein Rest von 2 oder 3 Byte bei best-fit.

Ohne automatische Speicherbereinigung kann es durch Fragmentierung des zur Verfügung stehenden Gesamtspeicherbereiches so weit kommen, dass neue Speicheranforderungen nicht mehr erfüllt werden können, obwohl der insgesamt verfügbare freie Speicher noch ohne Weiteres ausreichen würde. Der Grund ist, dass auch der virtuelle Adressraum, auf den sämtliche Adressen abgebildet werden müssen, nicht unbegrenzt ist. Bei einem 32-Bit-Betriebssystem hat der virtuelle Adressraum je Prozess eine Maximalgröße von 4 GB, von dem das Betriebssystem selbst gewöhnlich einen erheblichen Anteil für sich beansprucht.

Weiterführende Artikel

  • Speicherüberlauf bei der dynamischen Speicheranforderung. Siehe Heap Overflow.