Webcam Diggs Cam


Speichermanagment

Kapitel 6 - Speichermanagment

Inhalt
  • Freispeicherverwaltung durch Bitmaps, Listen und Buddy
  • Mehrdimensionale Adressräume durch Segmentierung
  • virtueller Speicher durch Paging
  • Zusammenwirken von Segmentierung und Paging
  • Adressumrechnung am Beispiel
Übersicht zur Freispeicherverwaltung

Es gibt drei grundlegende Ansätze zur Verwaltung des freien Speichers. Diese werden im folgendem Text erläutert.

Was sind Bitmaps?

Bitmaps teilen den Hauptspeicher in gleich große Einheiten und assoziieren zu jedem Eintrag ein Bit in der Bitmap. Ist der Eintrag 0, so ist der Speicherbereich noch frei. Bei Nutzung eines Speicherbereiches wird in dem assoziierenden Bitmapplatz eine eins platziert. Umso kleiner die zusammengefassten Einheiten werden, umso größer wird die Bitmap. Der größte Nachteil von Bitmaps ist das Suchen von freien Speicherbereichen, was eine aufwendige Operation darstellt.

Welche Möglichkeiten der Suche in Freispeicherlisten gibt es?

Bei dieser Variante werden Listen für Löcher und belegte Segmente durch Prozesse geführt.


First Fit

Der erste freie Block der groß genug ist wird ausgewählt, egal wieviel Speicher dadurch verschwendet wird (interne Fragmentierung).

Next Fit

Suche beginnt nicht vom Anfang der Liste, sondern vom zuletzt verwendeten Listenelement.

Best Fit

Es wird der optimale Platz in Bezug auf Speicherausnutzung gesucht. Dadurch das immer Blöcke mit der geringsten Speicherplatzverschwendung gesucht werden, werden die freien Blöcke irgendwann zu klein.

Quick Fit

Es gibt mehrere Listen für verschiedene Blockgrößen.

Wie funktionieren Buddy Listen?

Listen haben den Nachteil, daß benachbarte freie oder belegte Speicherbereiche sich nicht zusammenlegen lassen. Abhilfe schafft hier das Buddy-System. Die Idee beruht darauf, dass mehrere Listen geführt werden, welche aber nur Blockgrößen von 2^n zulassen. Zweierpotenz deshalb, weil ein Rechner Binärzahlen zur Adressierung benutzt.

Beispiel:

Die maximale Blockgröße beträgt 64 Mbytes und die minimale Blockgröße 4 Kbyte. D.h. 226 - 212, also müssen Listen für N=12 bis N=26 verwaltet werden. Somit wären für diese Blockgrößenwahl mit dem Buddysystem 15 Listen notwendig.

Anfragen werden nun immer zur nächsthöhren Zweierpotenz aufgerundet. D.h. wird eine Anfrage an einen 75 Kbyte Block gestellt, muss ein 128 Kbyte großer Slot verwendet werden. Anfangs gibt es eine Liste für in unserem Beispiel 64 Mbyte Speicher. Der Buddymanager würde die Liste rekursiv so oft teilen, bis ein 128 Kbyte großer Block in eine der anderen Listen frei ist.

Falls die angeforderten Blockgrößen aussschliesslich Zweierpotenzen wären, würde es zu keiner Internen Fragmentierung kommen können. Da dies aber nie der Fall ist, wird viel Speicher durch interne Fragmentierung verschwendet.

Zusammenfassung Freispeicherverwaltung

Bitmaps unterteilen den Speicher in Allokationseinheiten. Für jede Einheit gibt es ein Bit im Bitmap. Verknüpfte Listen bieten Suchmöglichkeiten mit First Fit, Best Fit oder Quick Fit. Quick Fit setzt mehrere Listen bestimmter Lochgößen voraus. Das Buddy System verwaltet n Listen von 1,2, 4, 8 bis zur Größe des Speichers. D.h. ein 1 MByte großer Speicher benötigt 21 Listen und hat Initial nur einen einzigen Eintrag in der letzten Liste, der das 1 MByte große Loch beschreibt. Alle anderen Listen sind leer. Speicher wird nun immer in Abhängigkeit von einer Potenz von 2 vergeben, der gerade noch groß genug ist, um die Daten aufzunehmen. Dies wird einfach implementiert, in dem der Große block einfach solange geteilt wird, bis der Datenblock in den Freispeicherblock passt. Das Buddysystem ist zwar schnell, aber impliziert eine starke interne Fragmentation, da ja immer auf Zweierpotenzen gerundet werden muss.


  • einfache verkettete Listen mit Best-,Next- oder First-Fit Suche
  • Bitmap-System welches Speicher in gleichgroße Einheiten teilt
  • Buddy-Listen nach dem binären System
Merktabelle: Methoden zur Freispeicherverwaltung

Wie arbeitet Segmentierung (mehrdimensionale Adressräume)?

Eindimensionale Adressierung hat den Nachteil, daß Programme mit verschieden dynamisch wachsenden Programmteilen nur schlecht realisierbar sind. Code, Stack und Daten würden hintereinander im Speicher liegen. Benötigt ein Programm aber extrem viele Variablen, würde der Compiler mit der Fehlermeldung abbrechen, daß es nicht genug Speicher gäbe. Um nun mehrere Stack, Daten und Codebereiche getrennt voneinander adressieren zu können, ohne daß die verschiedenen Teile in Konflikt geraten, wurden die Segmente eingeführt.

Segmentierte Speicherung wird oft als das Prinzip der gestreuten Speicherung benannt. Gestreut deshalb, weil die einzelnen Seiten nicht nacheinander im Speicher liegen müssen, sondern dort eingefügt werden, wo Platz ist. Anders als z.B. bei Kontinuierlicher Allokation, wo viel Speicher durch externe Fragmentierung verlorengeht, tritt bei Segmentation dieses Problem nicht auf. Dafür aber interne Fragmentierung...

Wie werden Segmenten adressiert?

Um mit Segmenten arbeiten zu können, sind zweiteilige Adressen notwendig, bestehend aus Segment und Offset. Die Segmentation muss also dem Programmierer bewusst sein, da ein Segment nur eine logische Einheit darstellt. Besonders einfach gestaltet sich das übersetzen von Prozeduren. Angenommen jede Prozedur hat ihr eigenes Codesegment, benötigt man nur die Segmentnummer, um die Funktion aufzurufen, da der Eintrittspunkt bei der logischen Adresse 0 dieses Segmentes ist.
Wird nun eine Prozedur neu kompiliert, müssen die restlichen Prozeduren nicht neu kompiliert werden, da der Eintrittspunkt immer noch der gleiche ist. Und zwar 0. Die Segmentnummern werden eh dynamisch vergeben.

Was versteht man unter gemeinsam genutzten Segmenten?

Durch Segmentierung wird es sehr einfach, verschiedene Codesegmente gemeinsam zu nutzen. So genannte Shared Libraries sind in jedem modernen Betriebssystem notwendig, denn sie stellen für viele Programme Frameworks oder API's bereit, deren Funktionalität sich jedes Programm bedienen kann, soweit es die dafür notwendigen Zugriffsrechte hat. Ob ein Segment ausführbar ist oder nicht, wird über die Schutzart des Segmentes definiert.

Wie funktioniert das Prinzip des virtuellen Speichers durch Paging?

Um mehr Speicher bereitzustellen werden statt echter physikalischer Adressen virtuelle benutzt, welche durch die MMU in reale Adressen bei Benutzung umgewandelt werden. Durch das Paging können Seiten aus- oder eingelagert (nach einem Page Fault) werden. Eine Page Table referenziert virtuelle auf physikalische Adressen. Swapping ist in Reinform sehr langsam. Sinnvollerweise werden Segmente in Seiten geteilt, welche durch Paging ein oder ausgelagert werden. (Protected Mode) Die MMU kann, muss aber nicht auf der CPU liegen. Jede Seitentabelleneintrag hat ein Present/Absent Bit, welches Auskunft darüber gibt, ob eine Seite sich im Speicher befindet oder nicht. Des Weiteren vermerkt eine Art Dirty Bit, ob eine Seite im Speicher geändert wurde, um entscheiden zu können, ob ein zurück schreiben notwendig wird.

Die momentan verwendeten Seiten eines Programmablaufes wird Working Set genannt. Demand Paging bedeutet, dass Seiten erst dann abgefordert werden, wenn sie benötigt werden.

Eine virtuelle Adresse besteht aus Seitenummer und Offset. Bei einem Contextswitch wird nach der entsprechenden Seitennummer in der Page Table gesucht und die zugehörige physikalische Adresse errechnet. Es wird meist ein n-stufiges Paging angewandt, um die Suche mach den Seiten zu beschleunigen (Unix) . Bei i386 gibt es ein so genanntes Seitenverzeichnis (DIR) mit 1024 Zeilen, welche wiederum je auf eine Seitentabelle verweisen. Somit enthält eine lineare Adresse beim Intel DIR,PAGE und OFFSET Teil. (mehrstufiges Paging)

Beim Swapping werden statt Seiten ganze Prozesse ausgelagert.


  • Demand Paging und Caching basieren auf den gleichen Prinzip
  • Sie arbeiten nur auf verschiedenen Ebenen
  • Cache-Misses werden von der Hardware geregelt, Page Faults vom Betriebssystem
Merktabelle: Virtual Memory und Caching

Was ist der Translation Lookaside Buffer?

Um die Zeit der Adressumrechnung zu vermindern, wird in der MMU ein Assoziativspeicher mit meist nicht mehr als 32 Einträgen verwaltet. Die Einträge enthalten die zuletzt verwendeten virtuellen Seiten mit der dazugehörigen Seitenrahmennummer im Speicher. Gleichzeitig wird dort vermerkt, welche Art von Lese/Schreibzugriff erlaubt ist und ob die Seite verändert wurde. Kommt eine Anforderung auf eine nicht im TLB vorhandene Seite, wird ein Eintrag aus dem TLB mit der neu dekodierten Adresse überschrieben, so daß bei der nächsten Anfrage die Adressumrechnung entfallen kann.


  • TLB's werden verwendet, wenn Seitentabelle auf Grund eines zu großen Adressraumes nicht möglich ist
  • TLB bildet zuletzt genutzten (64 bei UltraSparc) virtuellen Seitennummern auf physikalische Seitenrahmen ab
  • häufig benutzte Seiten werden in einem Cache (Translation Storage Buffer) verwaltet
  • Dieser Cache bildet Seiten direkt ab und wird bei TLB-Miss zuerst untersucht
  • befindet sich die Seite nicht im Cache, muss sie in der Translation Table gesucht werden
Merktabelle: Translation Lookaside Buffer

Was sind invertierte Page Tables?

Eine Seitentabelle enthält hier einen Eintrag für jeden Seitenrahmen des physikalischen Speichers. Der Eintrag enthält Informationen über den besitzenden Prozess und die virtuelle Seite. So entspricht die Anzahl der Einträge der Anzahl der Seitenrahmen im Speicher. Die Tabelle verwaltet nur, welche Seite, von welchem Prozess in den Seitenrahmen des Arbeitsspeicher geladen wurden.

Was sind Paging Dämons?

Paging arbeitet nur effizient, wenn jederzeit genügend Seitenrahmen im Speicher frei sind, um diese bei einem Page Fault neuen Seiten belegen zu können. Doch wie wird sichergestellt, daß der Speicher komplett ausgefüllt werden muss und somit bei einem Page Fault erst eine Seite ausgelagert werden muss? Viele Betriebssysteme haben dafür einen speziellen Dienst vorgesehen. Der Paging Dämon wird in zyklischen Abständen aktiviert. Dieser schaut nun nach ob genügend Frames im Speicher zur Verfügung stehen. Ist dies nicht der Fall, werden so viele Seiten wie notwendig mit einem der Seitenersetzungsalgorithmen aus dem Speicher entfernt und auf die Platte zurückgeschrieben.

Erklären Sie das Zusammenspiel von Segmentierung und Paging?

Um beide Vorteile (Mehrdimensionalität und virtuellen Speicher) nutzen zu können, werden in fast allen modernen Betriebssystemen beide Techniken angewandt. Dabei wird das Paging transparent, also für den Programmierer nicht sichtbar, hinter die Segmentierung geschalten. Auf dieser Basis bauen sich auch die Adressen dieser Maschinen auf. Es gibt verschiedene Implementationen von Segmentierung und Paging. Aber letztendlich haben sie eines gemeinsam. Die logische Adresse besteht aus
  1. die Segmentnummer zur Auswahl des richtigen Segmentdeskriptors und
  2. den Offset zur Adressierung innerhalb des Segmentes.
Die Implementierungen unterscheiden sich nun in der Verwaltung der Deskriptoren und der Art und Weise wie die aus Segment + Offset entstandene virtuelle Adresse über die Page Table auf den realen Speicher projiziert bzw. umgerechnet wird.

Adressumsetzung

Was passiert wenn Sie ein Programm starten?

  • Der Virtual Memory Manager verwaltet den virtuellen Speicher.
  • Bei Programmstart richtet das BS für den Prozess eine Seitentabelle ein.
  • Eine definierte Anzahl Rahmen werden dem Prozess als Arbeitsmenge zugeteilt.
  • Seiten aus dem Read-Only Bereich der EXE werden direkt geladen und brauchen nicht zurückgeschrieben werden.
  • Read-Write Bereiche werden zuerst direkt aus der EXE geladen und im Speicher hinterlegt.
  • Bei einem Schreib-Bezug wird sie als private Kopie in die Auslagerungsdatei geschrieben. So können mehrere Prozesse die selbe EXE im benutzen. (Copy On Write)
Der VMM von Windows verwaltet mehrere Listen für:
  • freie Seiten, welche mit 0 initialisiert wurden (zerofilled)
  • uninitialisierte freie Seiten, die noch alten Inhalt haben
  • wartende Seiten, die Prozess zugewiesen waren und nicht modifiziert wurden(standby pages)
  • wartende, aber modifizierte Seiten (modified pages)
  • belegte Seiten, welchen einem Prozess zugewiesen / referenziert sind (valid pages)
  • unbenutzbare Seiten, durch z.B. Hardwarefehler (unusable pages)

Wie arbeitet die Adressumrechnung der Multics?

  1. mit Segmentnummer wird Segmentdeskriptor festgestellt
  2. es wird geprüft, ob die Pagetable des Segmentes im Speicher ist
  3. ist sie nicht im Speicher tritt ein Segmentfehler auf und es erfolgt ein Trap
  4. ist sie im Speicher wird der Pagetableeintrag für die angefragte Seite überprüft
  5. falls Seite nicht im Speicher entsteht Page Fault
  6. ist Seite im Speicher wird die physikalische Adresse des Seitenursprungs aus dem Pagetableeintrag entnommen
  7. Der Offset wird zur gewonnenen Adresse hinzuaddiert und die physikalische Adresse ist berechnet.
(nach Tanenbaum)

Meist wird ein Assoziativspeicher verwendet, um die letzten paar Umrechnungen ohne Verzögerung ausgeben zu können. Ein TLB enthält zwei Vergleichsfelder für Segmentnummer und korrespondierende virtuelle Seite und einige zusätzliche Attribute, wie Schutzattribute, Age oder Referenziert-Bits.

Wie funktioniert die Adressumrechnung beim P2?

Intel Prozessoren besitzen ab dem i386 eine LDT (local descriptor table) und eine GDT (global descriptor table). Die Local Descriptor Tables enthalten die programmeigenen Segmente, wie Stack-, Code- und Datensegment der verschiedenen Benutzerprogramme. Die Global Descriptor Table enthält dagegen die Systemsegmente samt deren des Betriebssystems , welche erst geladen werden muss. Wird ein Segmentselektor in ein Segmentregister geladen, wird der entsprechende Bezeichner aus der LDT oder GDT geholt und in MMU Registern gespeichert. Ob L- oder GDT kann dem Selektor entnommen werden, da dort ein Bit für diese Auswahl reserviert ist. Der Deskriptor besteht nun aus der Basisadresse des Segmentes, der Größe des Segmentes und verschiedenen Privilegbits. Es wird nun eine virtuelle Adresse über Segmenteselektor + Offset gebildet. Bei deaktiviertem Paging ist nun diese Adresse die lineare physikalische. Ist aber Paging aktiv wird die Adresse als virtuell interpretiert und über die Seitentabelle auf den realen Speicher abgebildet.

Was haben Deskriptoren mit Sicherheit und Segmentverwaltung zu tun?

Jeder Deskriptor in einer Deskriptortabelle ist mehrere Byte breit und enthält Beschreibungsinformationen für ein Segment aus dem linearen Adressraum. Neben der Segment-Basisadresse (BASE) enthält er das LIMIT, das die Segmentgröße angibt. Dabei wird durch ein Granularitätsbit festgelegt, ob das LIMIT direkt als Länge interpretiert wird (Segmentgrößen bis 1 MB) oder mit dem Wert 4096 multipliziert wird und damit Segmentgrößen bis 4 GB unterstützt. Der Descriptor-Privilege-Level gibt an, mit welcher Berechtigungsstufe der Zugriff auf das Segment erfolgen muss:
  • Level 0: Betriebssystem
  • Level 1, 2: Betriebssystemdienste, Treiber, Systemsoftware
  • Level 3: Anwendungssoftware
Weitere Informationen im Deskriptor zeigen an, ob auf das Segment lesend, schreibend oder ausführend zugegriffen werden darf und ob es sich um ein System- oder Anwendungssegment handelt. Ein Present-Bit gibt an, ob das Segment sich derzeit überhaupt im Hauptspeicher befindet.

Zusammenfassung von Freispeicherverwaltung, Segmentierung und Paging

Segmentierung wird genutzt, um statt einen linearen Adressraum (wie beim virtuellen Speicher), mehrere virtuelle Adressräume nutzen zu können. Segmentierung wurde entworfen, um dynamisch wachsende Tabellen besser Handhaben zu können. Somit ist schafft Segmentierung einen mehrdimensionalen Adressraum.

Unter Swapping versteht man das komplette Ein- und Auslagern von Prozessen. Das Swapping des segmentierten Speichers ist vergleichbar mit dem Demand-Paging des virtuellen Speichers. Nur das Segmente unterschiedlich groß sein können. Aus diesem Grund tritt hier das Problem der externen Fragmentierung auf.

Um die externe Fragmentierung zu minimieren, werden die Löcher als verkettete Liste im Speicher gehalten. Falls ein Segment geladen werden soll, sucht z.B. Best Fit, dass nächst größere Loch unter allen, wo das Segment passen würde. First Fit nimmt das Nächste Loch, welches für das Segment groß genug wäre.

Neben dem Swapping kann auch Paging zum Auslagern von Segmenten benutzt werden. Hierbei sind die auszulagernden Blöcke gleich groß, da die Segmente in gleich große Seiten eingeteilt werden. Zur Auslagerung wird das bekannte Demand Paging benutzt. Meist wird eine Kombination aus Segmentierung und Paging angewandt, bei der die Adresse aus zwei Teilen besteht. (Segmentnummer und Offset innerhalb des Segments). Segmente werden also in Seiten unterteilt. Zur Leistungsverbesserung werden die zuletzt verwendeten Segment-Seiten- Kombinationen in einem Assoziativspeicher (TLB) gehalten. Im Gegensatz zum Paging ist es beim reinen Swapping nicht möglich, Prozesse auszuführen, die alleine schon nicht in den Hauptspeicher passen.

Bitmaps unterteilen den Speicher in Allokationseinheiten. Für jede Einheit gibt es ein Bit im Bitmap. Verknüpfte Listen bieten Suchmöglichkeiten mit First Fit, Best Fit oder Quick Fit. Quick Fit setzt mehrere Listen bestimmter Lochgößen voraus. Das Buddy System verwaltet n Listen von 1,2, 4, 8 bis zur Größe des Speichers. D.h. ein 1 MByte großer Speicher benötigt 21 Listen und hat Initial nur einen einzigen Eintrag in der letzten Liste, der das 1 MByte große Loch beschreibt. Alle anderen Listen sind leer. Speicher wird nun immer in Abhängigkeit von einer Potenz von 2 vergeben, der gerade noch groß genug ist, um die Daten aufzunehmen. Dies wird einfach implementiert, in dem der Große block einfach solange geteilt wird, bis der Datenblock in den Freispeicherblock passt. Das Buddysystem ist zwar schnell, aber impliziert eine starke interne Fragmentation, da ja immer auf Zweierpotenzen gerundet werden muss.
Printansicht Inhalt Anfang zurück vor
Kapitel 1Einleitung
Ebenen- oder Schichtenmodell, Aufgaben...
Kapitel 2Modelle
Schichtenmodell, Betriebsmittel, Instanzen...
Kapitel 3Aktivitäten
Token, Multitasking, Prozesse,Timesharing...
Kapitel 4Kritischer Abschnitt
Gegenseitiger Ausschluss,Peterson,Semaphore...
Kapitel 5Scheduling
Prozessorzuteilung, Prioritätsscheduling, RR...
Kapitel 6Speichermanagment
Freispeicherverwaltung, Segmentierung, Paging...
Kapitel 7Seitenersetzung
NRU, FiFo, Second Chance, LRU, NFU, Aging...
Kapitel 8Deadlocks
Bedingungen, Erkennung und Auflösung...
Kapitel 9Dateisysteme
Freispeicherverwaltung, Festplattenscheduling...
UNIX Codes
Unix Prozesse
Kommunikation
Quellen:
Andrew S. Tanenbaum
Computerarchitektur
Andrew S. Tanenbaum
Moderne Betriebssysteme
Petterson
Computer Architectur & Design
Christian Märtin
Rechnerarchitekturen
Kalfa
Skript und Vorlesung
Word Wide Web
Verschiedenste Seiten
Links:
Prozesse
FH-Bielefeld

login

last change 06.04.2008 16:28:48  © 2002 - 2005 Holger Kreissl