| Zeile 2: | Zeile 2: | ||
== Einleitung == | == Einleitung == | ||
| − | Generell ist die Speicherverwaltung dafür zuständig nachfragenden Prozessen freien Speicher zuzuteilen bzw. freizugebenden Speicher wieder zurückzunehmen. Dazu muss natürlich gespeichert werden, welche Speicherbereiche belegt bzw. frei sind. Es ist wichtig zu verstehen, dass die Speicherverwaltung normalerweise auf drei Ebenen aufgeteilt wird: | + | Generell ist die Speicherverwaltung dafür zuständig, nachfragenden Prozessen freien Speicher zuzuteilen bzw. freizugebenden Speicher wieder zurückzunehmen. Dazu muss natürlich gespeichert werden, welche Speicherbereiche belegt bzw. frei sind. Es ist wichtig zu verstehen, dass die Speicherverwaltung normalerweise auf drei Ebenen aufgeteilt wird: |
* Die [[physische Speicherverwaltung]] verwaltet Speicherblöcke (physische Seiten) im tatsächlich verfügbaren RAM | * Die [[physische Speicherverwaltung]] verwaltet Speicherblöcke (physische Seiten) im tatsächlich verfügbaren RAM | ||
| Zeile 9: | Zeile 9: | ||
== Physische Speicherverwaltung == | == Physische Speicherverwaltung == | ||
| − | + | ''Hauptartikel: [[Physische Speicherverwaltung]]'' | |
| − | + | Die '''Physische Speicherverwaltung''' bildet die unterste Ebene und ermöglicht das Allozieren und Freigeben von physischen Speicherbereichen. Meist sind diese Speicherbereiche gleich groß und richten sich nach der Seitengröße der jeweiligen Architektur. Die Seitengröße beträgt normalerweise bei der [[x86]]- und [[x86-64]]-Architektur 4 kB. Es sind dort auch 4 ([[x86]]) bzw. 2 MB ([[x86-64]]) möglich. Intern speichert die physische Speicherverwaltung, welche Speicherbereiche im physischen Speicher frei sind. | |
== virtuelle Speicherverwaltung == | == virtuelle Speicherverwaltung == | ||
| + | ''Hauptartikel: [[Paging]]'' | ||
| + | |||
Die '''virtuelle Speicherverwaltung''' befindet sich eine Schicht über der [[ #physische Speicherverwaltung | physischen Speicherverwaltung]] und ist für die Organisation der Speicherbereiche im virtuellen Adressraum eines Prozesses zuständig. Unter [[x86]] und [[x86-64]] beispielsweise wird ein virtueller Adressraum über den [[Paging | Paging-Mechanismus]] (siehe dort für eine genauere Erklärung) realisiert. Dieser virtuelle Adressraum hat erstmal nichts mit dem physischen Adressraum gemeinsam. Erst die virtuelle Speicherverwaltung stellt durch Ein- und Ausblenden von physischen Speicherseiten in den virtuellen Adressraum diese Verbindung her und blendet die Segmente des Prozessimage (Code, Daten, nicht initialisierte Daten, ...), den Heap, den Stack, benötigte shared-libraries, [[IPC#Shared-memory | shared-memory]], auch den Kernel, etc. in den virtuellen Adressraum ein oder aus. Die dafür benötigten physischen Speicherseiten werden der physischen Speicherverwaltung entnommen. | Die '''virtuelle Speicherverwaltung''' befindet sich eine Schicht über der [[ #physische Speicherverwaltung | physischen Speicherverwaltung]] und ist für die Organisation der Speicherbereiche im virtuellen Adressraum eines Prozesses zuständig. Unter [[x86]] und [[x86-64]] beispielsweise wird ein virtueller Adressraum über den [[Paging | Paging-Mechanismus]] (siehe dort für eine genauere Erklärung) realisiert. Dieser virtuelle Adressraum hat erstmal nichts mit dem physischen Adressraum gemeinsam. Erst die virtuelle Speicherverwaltung stellt durch Ein- und Ausblenden von physischen Speicherseiten in den virtuellen Adressraum diese Verbindung her und blendet die Segmente des Prozessimage (Code, Daten, nicht initialisierte Daten, ...), den Heap, den Stack, benötigte shared-libraries, [[IPC#Shared-memory | shared-memory]], auch den Kernel, etc. in den virtuellen Adressraum ein oder aus. Die dafür benötigten physischen Speicherseiten werden der physischen Speicherverwaltung entnommen. | ||
| − | Die virtuelle Speicherverwaltung übernimmt in einem Multiprozessorsystem auch die Aufgabe die virtuellen Adressräume über mehrere Prozessoren hinweg konsistent zu halten (siehe auch [[SMP]]). | + | Die virtuelle Speicherverwaltung übernimmt in einem Multiprozessorsystem auch die Aufgabe, die virtuellen Adressräume über mehrere Prozessoren hinweg konsistent zu halten (siehe auch [[SMP]]). |
| − | |||
| − | |||
== Implementierung von malloc()/free() == | == Implementierung von malloc()/free() == | ||
| Zeile 25: | Zeile 25: | ||
Gelegentlich werden die beiden Funktionen auch als Bestandteil der virtuellen Speicherverwaltung bezeichnet, da sie ebenfalls mit virtuellen Adressen arbeiten. Sie sind aber nicht mit [[Paging]] zu verwechseln. | Gelegentlich werden die beiden Funktionen auch als Bestandteil der virtuellen Speicherverwaltung bezeichnet, da sie ebenfalls mit virtuellen Adressen arbeiten. Sie sind aber nicht mit [[Paging]] zu verwechseln. | ||
| − | Es gibt verschiedene Möglichkeiten malloc() bzw. free() zu implementieren. Eine Möglichkeit ist es vor den Speicherblöcken Header anzulegen, die die Länge, Flags (wie z.B ob der Block frei ist) und gegenfalls einen Pointer auf den nächsten freien Block beinhalten. Zum Anfang sind keine freien Blöcke vorhanden. Es wird vom Kernel eine Page angefordert. Nun wird ein Header an den Anfang der Page gesetzt. Wenn nun malloc() aufgerufen wird, wird der Block aufgeteilt und ein Teilblock als benutzt markiert. Bei einem Aufruf von free() wird der Block als frei markiert und in die Liste der freien Blöcke eingefügt. Wenn benachbarte Blöcke auch frei sind, werden diese zusammengefügt. Wenn man nun eine ganze Page hat, die als frei markiert ist, kann sie vom Kernel freigegeben werden oder aufgehoben werden, bis sie wieder gebraucht wird. | + | Es gibt verschiedene Möglichkeiten malloc() bzw. free() zu implementieren. Eine Möglichkeit ist es, vor den Speicherblöcken Header anzulegen, die die Länge, Flags (wie z.B ob der Block frei ist) und gegenfalls einen Pointer auf den nächsten freien Block beinhalten. Zum Anfang sind keine freien Blöcke vorhanden. Es wird vom Kernel eine Page angefordert. Nun wird ein Header an den Anfang der Page gesetzt. Wenn nun malloc() aufgerufen wird, wird der Block aufgeteilt und ein Teilblock als benutzt markiert. Bei einem Aufruf von free() wird der Block als frei markiert und in die Liste der freien Blöcke eingefügt. Wenn benachbarte Blöcke auch frei sind, werden diese zusammengefügt. Wenn man nun eine ganze Page hat, die als frei markiert ist, kann sie vom Kernel freigegeben werden oder aufgehoben werden, bis sie wieder gebraucht wird. |
Man kann auch eine der freien malloc()/free() Implementierungen portieren: | Man kann auch eine der freien malloc()/free() Implementierungen portieren: | ||