Wikipedia · einfach zusammengefasst · Stand
Speicherverwaltung
Das Verwalten der höheren Ebenen der Speicherhierarchie wie beispielsweise des Cache-Speichers wird dagegen üblicherweise von der Hardware vorgenommen.
Inhalt5 Abschnitte
Aufgabe der Speicherverwaltung
Die Speicherverwaltung (memory management) ist der Teil des Betriebssystems, der Teile der Speicherhierarchie verwaltet. Ihr wichtiges Ziel ist ein effizienter und komfortabler Zugriff auf den physischen Arbeitsspeicher (Hauptspeicher); deshalb spricht man auch von Hauptspeicherverwaltung. Höhere Ebenen wie der Cache werden üblicherweise durch Hardware verwaltet.
Eine Schlüsselfunktion ist meist ein virtueller oder logischer Adressraum für jeden Prozess. Er ist die Menge der Adressen, auf die ein Prozess zugreifen kann, und ist vom tatsächlich vorhandenen Arbeitsspeicher entkoppelt: Er kann größer oder kleiner sein. Virtuelle Adressen gelangen zur Memory Management Unit (MMU, Speicherverwaltungseinheit), die sie auf physische Adressen abbildet. Üblicherweise befindet sich nur ein Teil eines Adressraums im RAM, während ein anderer auf der Festplatte liegt; bei Bedarf werden Programmteile verschoben.
In heutigen Multiuser-/Multiprogramming-Betriebssystemen wird meist virtuelle Speicherverwaltung eingesetzt, häufig mit Optimierungen des Demand-Paging-Verfahrens.
Speicherhierarchie und Lokalität
Ein Rechnersystem verwendet mehrere Speichertechnologien. Kurze Zugriffszeiten machen Speicher teurer und führen meist zu geringerer Kapazität. Die Speicherhierarchie versucht daher, Geschwindigkeit, Kosten und Persistenz sinnvoll zu verbinden.
- CPU-Register bilden die oberste Stufe. Sie liegen in der CPU, verursachen kaum Verzögerungen und werden durch Software kontrolliert. Ihre übliche Kapazität beträgt bei einem 32-Bit-Prozessor 32 × 32 Bit und bei einem 64-Bit-Prozessor 64 × 64 Bit.
- Cache ist ein kleiner, schneller Puffer zwischen CPU und Hauptspeicher. Er enthält Kopien häufig benutzter Hauptspeicherbereiche. Moderne CPUs besitzen oft zwei oder mehr Cache-Levels; der Cache wird meist durch Hardware kontrolliert.
- Der Arbeitsspeicher (RAM) enthält gerade auszuführende Programme oder Programmteile sowie deren Daten. Anfragen, die der Cache nicht beantwortet, gehen an den RAM. Üblicher RAM ist flüchtig: Ohne Strom gehen die Daten verloren.
- Massenspeicher speichern Daten dauerhaft. Magnetische Festplatten sind pro Bit etwa um den Faktor 100 billiger als RAM und haben meist die 100-fache Kapazität; ihr wahlfreier Zugriff dauert jedoch etwa 100.000-mal länger. Daten müssen vor der Verarbeitung erst in den Hauptspeicher geladen werden. Massenspeicher heißen daher auch Hintergrund- oder Sekundärspeicher.
- Zusätzlich gibt es Wechseldatenträger wie DVD, CD, USB-Stick, Disketten und Magnetband.
Der Memory Manager verfolgt belegte Bereiche, teilt Prozessen Speicher zu und gibt ihn später frei. Dabei lässt sich Lokalität ausnutzen: Zeitliche Lokalität bedeutet, dass kürzlich verwendete Adressbereiche wahrscheinlich bald wieder gebraucht werden. Räumliche Lokalität bedeutet, dass nach einer Adresse wahrscheinlich eine benachbarte Adresse angesprochen wird. Deshalb können beim Zugriff auch benachbarte Bereiche in die nächste Hierarchiestufe gebracht werden.
Direkte Verwaltung, Monoprogramming und Partitionen
Bei direkter Speicherverwaltung gibt es keine Speicherabstraktion: Ein Programm sieht direkt physische Adressen von 0 bis zu einem Maximum; jede Adresse gehört zu einer Zelle mit einer bestimmten Bitzahl. Auf Großrechnern, Minirechnern und PCs wird dies heute nicht mehr verwendet. Eingebettete Systeme und Smartcards nutzen es teilweise noch, weil ihre Programme im Voraus bekannt sind und meist im ROM liegen.
Beim Monoprogramming werden Arbeitsspeicher nur dem Betriebssystem und dem gerade aktiven Programm zugeteilt. Es läuft stets nur ein Prozess, der exklusiv auf den physischen Speicher zugreift. Die Verwaltung besteht im Wesentlichen darin, die angeforderte Adresse über den Datenbus zugänglich zu machen. Das Betriebssystem kann unten im RAM, oben im ROM oder – wie bei frühen PCs unter MS-DOS – mit Gerätetreibern oben im ROM und dem übrigen System unten im RAM liegen.
Mehrere Programme können auch bei direkter Verwaltung durch feste Partitionen gleichzeitig laufen. Der Arbeitsspeicher wird dazu in feste Teile geteilt, in denen jeweils genau ein Programm ausgeführt wird; ein Beispiel ist IBM OS/360. Schutzschlüssel verhindern Konflikte: Stimmt der Schutzcode eines Speicherblocks nicht mit dem PSW-Schlüssel (Programmstatuswort) eines Prozesses überein, wird ein Systemaufruf ausgelöst.
Swapping und dynamische Speicherzuteilung
Beim Swapping werden Daten zwischen Arbeitsspeicher und Festplatte verschoben. Es wird eingesetzt, weil der Speicherbedarf aller laufenden Prozesse oft größer ist als das vorhandene RAM. Ein Prozess wird vollständig in den Arbeitsspeicher geladen, darf eine Zeit laufen und wird danach wieder auf die Festplatte ausgelagert. So kann Swap-Speicher Anforderungen bedienen, die über den verfügbaren RAM hinausgehen.
Im Unterschied zu festen Partitionen können Anzahl, Größe und Ort der Prozesse variieren. Prozesse werden an freie Stellen geladen und können etwa durch Speicherreservierung auf einem Heap wachsen. Reicht der reservierte Bereich nicht mehr, kann ein Prozess in eine angrenzende Lücke wachsen, in eine größere Lücke verschoben werden oder andere Prozesse müssen ausgelagert werden.
Dadurch können ungenutzte Lücken entstehen; dies heißt Fragmentierung. Speicherverdichtung würde alle Prozesse möglichst weit nach unten verschieben und die Lücken zu einer großen Lücke oben zusammenfassen, ist aber sehr zeitaufwendig und wird normalerweise nicht eingesetzt.
Für dynamische Zuteilung verwendet das Betriebssystem Bitmaps oder verkettete Listen. Bei einer Bitmap wird der Speicher in Allokationseinheiten fester Größe geteilt; ein Bit zeigt an, ob eine Einheit belegt (=1) oder frei (=0) ist. In einer nach Startadressen sortierten verketteten Segmentliste beschreibt jeder Eintrag entweder eine Lücke (L) oder einen Prozess (P) mit Startadresse, Länge und Zeiger auf den nächsten Eintrag. Anders als beim Swapping kann bei virtuellem Speicher ein Programm laufen, obwohl nur ein Teil von ihm im RAM liegt; damit sind auch Programme möglich, die größer als der Hauptspeicher sind.
Virtueller Speicher: Adressraum, Paging und Segmente
Das Konzept der virtuellen Speicherverwaltung wurde 1961 erstmals von John Fotheringham beschrieben. Es erlaubt, dass Programmcode, Daten und Stack größer als der vorhandene Hauptspeicher sind. Bei realer Speicherverwaltung darf ein Prozess dagegen höchstens so groß wie der Hauptspeicher sein.
Virtuelle Adressen eines Programms bilden seinen virtuellen Adressraum und werden von der MMU in physische Adressen übersetzt. Greift ein Programm auf einen bereits im physischen Speicher vorhandenen Bereich zu, kann die Hardware die Zuordnung schnell durchführen. Fehlt der Bereich, wird das Betriebssystem alarmiert, beschafft ihn und führt den fehlgeschlagenen Befehl erneut aus. Die Größe des physischen Speichers hängt vom installierten RAM ab, die Größe des virtuellen Adressraums von der Befehlssatzarchitektur: Ein 32-Bit-Prozessor kann maximal 2^32 Byte, also 4 GB, adressieren; ein 64-Bit-System 2^64 Byte, also 16 Exabytes, auch wenn beispielsweise nur 512 MB RAM installiert sind. Multiprogramming profitiert davon, weil die CPU einem anderen Prozess zugeteilt werden kann, während ein Programm auf einzulesende Teile wartet.
Beim Paging wird der virtuelle Adressraum in gleich große Seiten und der physische Speicher in gleich große Seitenrahmen oder Kacheln geteilt. Typische Seitengrößen liegen bei 4 KByte; reale Systeme verwenden 512 Byte bis 4 MByte, teils auch 1 GB. Eine Seitentabelle enthält die Zuordnung. Fehlt eine Zuordnung, entsteht ein Seitenfehler (page fault) mit synchroner Programmunterbrechung (trap). Das Betriebssystem wählt dann einen wenig benutzten Seitenrahmen, schreibt dessen Inhalt auf die Festplatte zurück, lädt die benötigte Seite, ändert die Tabelle und wiederholt den Befehl. Demand Paging lädt Seiten erst bei tatsächlichem Bedarf. Prepaging kann zusätzlich noch nicht angeforderte, etwa benachbarte Seiten laden.
Bei der Segmentierung bestehen unabhängige Adressräume aus unterschiedlich großen, meist größeren Segmenten. Ein Segment ist eine logische Einheit, etwa eine Prozedur, ein Feld, ein Stack oder Variablen. Es kann während der Ausführung wachsen. Segmentierung passt zu natürlichen Programm- und Datengrenzen und unterstützt gemeinsam genutzte Programme: Ein eintrittsinvariant geschriebenes Programm kann einmal als Segment geladen und von mehreren Benutzern mit eigenen Datenbereichen genutzt werden. Nachteile sind aufwendige Algorithmen gegen Fragmentierung sowie mögliche Redundanz bei großen Segmenten, von denen oft nur ein Teil gebraucht wird.
Paged Segments kombinieren beide Verfahren: Jedes Segment wird in gleich große Seiten aufgeteilt. Eine Adresse enthält Segmentnummer, Seitennummer und die relative Byte-Adresse innerhalb der Seite.