Software läuft auf dem Betriebssystem unter einer sehr einfachen Voraussetzung - sie benötigt Speicher. Das Betriebssystem des Geräts stellt es in Form von RAM zur Verfügung. Die erforderliche Speichermenge kann variieren - einige Softwareprogramme benötigen großen Speicher, andere benötigen nur wenig Speicher. Die meisten (wenn nicht alle) Benutzer führen mehrere Anwendungen gleichzeitig auf dem Betriebssystem aus. Da der Speicher teuer ist (und die Gerätegröße begrenzt ist), ist die verfügbare Speichermenge immer begrenzt. Da alle Softwareprogramme eine bestimmte Menge an RAM benötigen und alle gleichzeitig ausgeführt werden können, muss sich das Betriebssystem um zwei Dinge kümmern:
- Dass die Software immer ausgeführt wird, bis der Benutzer sie abbricht, dh sie sollte nicht automatisch abgebrochen werden, da das Betriebssystem keinen Speicher mehr hat.
- Die oben genannte Aktivität unter Beibehaltung einer respektablen Leistung für die laufende Software.
Jetzt läuft die Hauptfrage darauf hinaus, wie der Speicher verwaltet wird. Was genau regelt, wo im Speicher die Daten einer bestimmten Software gespeichert werden?
Mögliche Lösung 1 : Lassen Sie einzelne Software explizit die Speicheradresse angeben, die sie im Gerät verwenden werden. Angenommen, Photoshop gibt an, dass immer Speicheradressen von 0
bis verwendet werden 1023
(stellen Sie sich den Speicher als lineares Array von Bytes vor, sodass sich das erste Byte am Speicherort befindet 0
, das 1024
Byte am Speicherort 1023
), dh den 1 GB
Speicher belegt. In ähnlicher Weise erklärt VLC, dass es Speicherbereich 1244
bis 1876
usw. belegen wird.
Vorteile:
- Jeder Anwendung ist ein Speichersteckplatz vorab zugewiesen. Wenn sie installiert und ausgeführt wird, werden ihre Daten nur in diesem Speicherbereich gespeichert, und alles funktioniert einwandfrei.
Nachteile:
Dies skaliert nicht. Theoretisch benötigt eine App möglicherweise sehr viel Speicher, wenn sie etwas wirklich Schweres tut. Um sicherzustellen, dass der Speicher nie knapp wird, muss der ihm zugewiesene Speicherbereich immer größer oder gleich dieser Speichermenge sein. Was ist, wenn eine Software, deren maximale theoretische Speichernutzung ist 2 GB
(daher eine 2 GB
Speicherzuweisung aus dem RAM erforderlich ist ), auf einem Computer mit nur 1 GB
Speicher installiert wird ? Sollte die Software beim Start einfach abgebrochen werden und sagen, dass der verfügbare RAM kleiner als ist 2 GB
? Oder sollte es fortgesetzt werden und in dem Moment, in dem der erforderliche Speicher überschritten wird 2 GB
, einfach abbrechen und mit der Meldung aussteigen, dass nicht genügend Speicher verfügbar ist?
Es ist nicht möglich, eine Speicherverfälschung zu verhindern. Es gibt Millionen von Software, selbst wenn jeder von ihnen nur 1 kB
Speicher zugewiesen würde 16 GB
, würde der erforderliche Gesamtspeicher übersteigen , was mehr ist als die meisten Geräte bieten. Wie können dann verschiedene Software-Speicherplätze zugewiesen werden, die nicht in die Bereiche des anderen eingreifen? Erstens gibt es keinen zentralisierten Softwaremarkt, der regeln kann, dass sich eine neue Software bei der Veröffentlichung so viel Speicher aus diesem noch nicht besetzten Bereich zuweisen mussund zweitens, selbst wenn es solche gäbe, ist es nicht möglich, dies zu tun, weil die Nr. Die Anzahl der Softwareprogramme ist praktisch unendlich (daher ist unendlich viel Speicher erforderlich, um alle zu speichern), und der auf einem Gerät verfügbare Gesamtspeicher reicht nicht aus, um auch nur einen Bruchteil des erforderlichen Speichers aufzunehmen, wodurch das Eindringen in die Speichergrenzen einer Software unvermeidlich wird auf das eines anderen. Also , was passiert , wenn Photoshop Speicherplatz zugeordnet 1
zu 1023
und VLC zugeordnet 1000
zu 1676
? Was passiert, wenn Photoshop einige Daten vor Ort speichert 1008
, dann überschreibt VLC diese mit seinen eigenen Daten und später mit Photoshopgreift es zu und denkt, dass es die gleichen Daten sind, die dort zuvor gespeichert wurden? Wie Sie sich vorstellen können, werden schlimme Dinge passieren.
Wie Sie sehen, ist diese Idee also ziemlich naiv.
Mögliche Lösung 2 : Versuchen wir es mit einem anderen Schema, bei dem das Betriebssystem den größten Teil der Speicherverwaltung übernimmt. Software fordert immer dann, wenn sie Speicher benötigt, nur das Betriebssystem an, und das Betriebssystem passt sich dem entsprechend an. Say OS stellt sicher, dass bei jedem neuen Prozess, der Speicher anfordert, der Speicher von der niedrigstmöglichen Byteadresse zugewiesen wird (wie bereits erwähnt, kann RAM als lineares Array von Bytes betrachtet werden, sodass für einen 4 GB
RAM der Adressbereich für a Byte von 0
bis2^32-1
) Wenn der Prozess gestartet wird, andernfalls, wenn es sich um einen laufenden Prozess handelt, der den Speicher anfordert, wird er vom letzten Speicherort zugewiesen, an dem sich dieser Prozess noch befindet. Da die Software Adressen ausgibt, ohne zu berücksichtigen, wie die tatsächliche Speicheradresse sein wird, an der diese Daten gespeichert werden, muss das Betriebssystem pro Software eine Zuordnung der von der Software ausgegebenen Adresse zur tatsächlichen physischen Adresse vornehmen (Hinweis: Dies ist einer der beiden Gründe, warum wir dieses Konzept nennen Virtual Memory
: Software kümmert sich nicht um die tatsächliche Speicheradresse, unter der ihre Daten gespeichert werden, sondern spuckt nur im laufenden Betrieb Adressen aus, und das Betriebssystem findet den richtigen Ort, um sie anzupassen und zu finden später bei Bedarf).
Angenommen, das Gerät wurde gerade eingeschaltet, das Betriebssystem wurde gerade gestartet. Derzeit wird kein anderer Prozess ausgeführt (das Betriebssystem wird ignoriert, was ebenfalls ein Prozess ist!), Und Sie entscheiden sich, VLC zu starten . Daher wird VLC ein Teil des RAM von den niedrigsten Byteadressen zugewiesen. Gut. Jetzt, während das Video läuft, müssen Sie Ihren Browser starten, um eine Webseite anzuzeigen. Dann müssen Sie Notepad starten, um Text zu kritzeln. Und dann Eclipse , um etwas zu programmieren. Ziemlich bald ist Ihr Speicher 4 GB
voll und der RAM sieht folgendermaßen aus:
Problem 1: Jetzt können Sie keinen anderen Prozess starten, da der gesamte RAM belegt ist. Daher müssen Programme unter Berücksichtigung des maximal verfügbaren Speichers geschrieben werden (praktisch noch weniger wird verfügbar sein, da andere Software ebenfalls parallel ausgeführt wird!). Mit anderen Worten, Sie können auf Ihrem baufälligen 1 GB
PC keine App mit hohem Speicherbedarf ausführen .
Okay, jetzt entscheiden Sie, dass Sie Eclipse und Chrome nicht mehr geöffnet lassen müssen. Sie schließen sie, um Speicherplatz freizugeben. Der von diesen Prozessen im RAM belegte Speicherplatz wird vom Betriebssystem zurückgefordert, und es sieht jetzt so aus:
Angenommen, durch das Schließen dieser beiden wird 700 MB
Speicherplatz freigegeben - ( 400
+ 300
) MB. Jetzt müssen Sie Opera starten , das 450 MB
Platz beansprucht. Nun, Sie haben insgesamt mehr als nur 450 MB
Platz zur Verfügung, aber ... es ist nicht zusammenhängend, es ist in einzelne Teile unterteilt, von denen keiner groß genug ist, um zu passen 450 MB
. Wenn Sie also auf eine brillante Idee gestoßen sind, verschieben wir alle Prozesse unten so weit wie möglich nach oben, sodass der 700 MB
leere Raum in einem Block unten verbleibt. Das nennt mancompaction
. Großartig, außer dass ... alle Prozesse, die dort sind, ausgeführt werden. Das Verschieben bedeutet, dass die Adresse aller Inhalte verschoben wird (denken Sie daran, dass das Betriebssystem eine Zuordnung des von der Software ausgespuckten Speichers zur tatsächlichen Speicheradresse beibehält. Stellen Sie sich vor, die Software hat eine Adresse 45
mit Daten ausgespuckt 123
und das Betriebssystem hat sie an einem Ort gespeichert 2012
und einen Eintrag in der Karte erstellt, Mapping 45
auf 2012
. Wenn die Software nun im Speicher bewegt wird, verwendet , was an dem Ort zu sein , 2012
wird nicht länger auf 2012
, sondern in einer neuen Position, und O hat , um die Karte zu aktualisieren entsprechend abzuzubilden , 45
um die neue Adresse, damit die Software die erwarteten Daten ( 123
) abrufen kann, wenn sie nach dem Speicherort fragt 45
. Was die Software betrifft, ist alles, was sie weiß, diese Adresse45
enthält die Daten 123
!)! Stellen Sie sich einen Prozess vor, der auf eine lokale Variable verweist i
. Wenn erneut darauf zugegriffen wird, hat sich die Adresse geändert und kann nicht mehr gefunden werden. Das Gleiche gilt für alle Funktionen, Objekte, Variablen. Grundsätzlich hat alles eine Adresse. Wenn Sie einen Prozess verschieben, müssen Sie die Adresse aller Funktionen ändern. Was uns führt zu:
Problem 2: Sie können einen Prozess nicht verschieben. Die Werte aller Variablen, Funktionen und Objekte in diesem Prozess haben fest codierte Werte, die vom Compiler während der Kompilierung ausgespuckt werden. Der Prozess hängt davon ab, dass sie sich während ihrer Lebensdauer am selben Ort befinden, und ihre Änderung ist teuer. Infolgedessen hinterlassen Prozesse holes
beim Beenden ein großes " ". Dies nennt man
External Fragmentation
.
Fein. Angenommen, Sie schaffen es auf wundersame Weise, die Prozesse nach oben zu bringen. Jetzt gibt es 700 MB
unten freien Speicherplatz:
Opera passt nahtlos in den unteren Bereich. Jetzt sieht Ihr RAM so aus:
Gut. Alles sieht gut aus. Es ist jedoch nicht mehr viel Platz übrig, und jetzt müssen Sie Chrome erneut starten , ein bekanntes Speicherproblem! Zum Starten wird viel Speicher benötigt, und Sie haben kaum noch Speicherplatz ... Außer ... Sie bemerken jetzt, dass einige der Prozesse, die ursprünglich viel Platz beanspruchten, jetzt nicht mehr viel Platz benötigen. Möglicherweise haben Sie Ihr Video in VLC gestoppt , daher nimmt es immer noch etwas Platz ein, aber nicht so viel, wie für die Ausführung eines hochauflösenden Videos erforderlich ist. Ähnliches gilt für Editor und Fotos . Ihr RAM sieht jetzt so aus:
Holes
, Noch einmal! Zurück zum ersten Platz! Außer dass die Löcher früher aufgrund von Prozessen aufgetreten sind, die beendet wurden, ist dies jetzt auf Prozesse zurückzuführen, die weniger Platz benötigen als zuvor! Und Sie haben wieder das gleiche Problem, die holes
kombinierten ergeben mehr Platz als erforderlich, aber sie sind verstreut, nicht viel isoliert zu nutzen. Sie müssen diese Prozesse also erneut verschieben, ein teurer und sehr häufiger Vorgang, da die Größe von Prozessen im Laufe ihrer Lebensdauer häufig abnimmt.
Problem 3: Prozesse können sich im Laufe ihrer Lebensdauer verkleinern und ungenutzten Speicherplatz hinterlassen, der bei Bedarf den teuren Vorgang des Verschiebens vieler Prozesse erfordert. Dies nennt man
Internal Fragmentation
.
Gut, jetzt erledigt Ihr Betriebssystem die erforderlichen Schritte, verschiebt Prozesse und startet Chrome. Nach einiger Zeit sieht Ihr RAM folgendermaßen aus:
Cool. Angenommen, Sie sehen Avatar erneut in VLC . Der Speicherbedarf steigt! Aber ... es ist kein Platz mehr zum Wachsen übrig, da sich der Editor unten ankuschelt. Also müssen wieder alle Prozesse nach unten verschoben werden, bis VLC genügend Platz gefunden hat!
Problem 4: Wenn Prozesse wachsen müssen, ist dies ein sehr teurer Vorgang
Fein. Angenommen, Fotos werden verwendet, um einige Fotos von einer externen Festplatte zu laden. Der Zugriff auf die Festplatte führt Sie vom Bereich der Caches und des Arbeitsspeichers zum Bereich der Festplatte, der um Größenordnungen langsamer ist. Schmerzlich, unwiderruflich, transzendental langsamer. Es ist eine E / A-Operation, was bedeutet, dass sie nicht an die CPU gebunden ist (es ist eher das genaue Gegenteil), was bedeutet, dass sie momentan keinen RAM belegen muss. Es belegt jedoch immer noch hartnäckig RAM. Wenn Sie Firefox in der Zwischenzeit starten möchten , können Sie dies nicht, da nicht viel Speicher verfügbar ist. Wenn Fotos für die Dauer ihrer E / A-gebundenen Aktivität aus dem Speicher genommen würden, hätte dies viel Speicher freigegeben. gefolgt von (teurer) Verdichtung, gefolgt von Firefox .
Problem 5: E / A-gebundene Jobs belegen weiterhin RAM, was zu einer Unterauslastung des RAM führt, das in der Zwischenzeit von CPU-gebundenen Jobs verwendet werden könnte.
Wie wir sehen können, haben wir selbst beim Ansatz des virtuellen Speichers so viele Probleme.
Es gibt zwei Ansätze, um diese Probleme anzugehen - paging
und segmentation
. Lassen Sie uns diskutieren paging
. Bei diesem Ansatz wird der virtuelle Adressraum eines Prozesses in Blöcken auf den physischen Speicher abgebildet pages
. Eine typische page
Größe ist 4 kB
. Die Zuordnung wird durch eine so genannte page table
virtuelle Adresse aufrechterhalten. Jetzt müssen wir nur noch herausfinden, zu welcher page
Adresse die Adresse gehört, und dann aus page table
der entsprechenden Position page
im tatsächlichen physischen Speicher (bekannt als frame
) den angegebenen Ort finden und angeben Wenn der Versatz der virtuellen Adresse innerhalb von sowohl page
für page
als auch für gleich ist frame
, ermitteln Sie die tatsächliche Adresse, indem Sie diesen Versatz zu der von der zurückgegebenen Adresse hinzufügen page table
. Beispielsweise:
Links befindet sich der virtuelle Adressraum eines Prozesses. Angenommen, der virtuelle Adressraum benötigt 40 Speichereinheiten. Wenn der physische Adressraum (rechts) ebenfalls 40 Speichereinheiten hätte, wäre es möglich gewesen, alle Standorte von links auf einen Standort rechts abzubilden, und wir wären so glücklich gewesen. Aber wie es das Pech hätte, verfügt der physische Speicher nicht nur über weniger (hier 24) Speichereinheiten, sondern muss auch von mehreren Prozessen gemeinsam genutzt werden! Gut, mal sehen, wie wir damit auskommen.
Wenn der Prozess startet, wird beispielsweise eine Speicherzugriffsanforderung für den Speicherort 35
gestellt. Hier ist die Seitengröße 8
(jeder page
enthält 8
Standorte, der gesamte virtuelle Adressraum von 40
Standorten enthält somit 5
Seiten). Dieser Ort gehört also zur Seite Nr. 4
( 35/8
). Innerhalb dieser page
Position hat diese Position einen Versatz von 3
( 35%8
). Dieser Ort kann also durch das Tupel (pageIndex, offset)
= angegeben werden (4,3)
. Dies ist nur der Anfang, sodass noch kein Teil des Prozesses im eigentlichen physischen Speicher gespeichert ist. Also die page table
, die eine Zuordnung der Seiten links zu den tatsächlichen Seiten rechts (wo sie aufgerufen werden) aufrechterhältframes
) ist derzeit leer. Das Betriebssystem gibt also die CPU frei, lässt einen Gerätetreiber auf die Festplatte zugreifen und ruft die Seiten-Nr. 4
für diesen Prozess (im Grunde ein Speicherblock aus dem Programm auf der Festplatte, dessen Adressen von 32
bis reichen 39
). Wenn es eintrifft, weist das Betriebssystem die Seite irgendwo im RAM zu, beispielsweise im ersten Frame selbst, und der page table
für diesen Prozess wird zur Kenntnis genommen, dass die Seite 4
dem Frame 0
im RAM zugeordnet ist. Jetzt sind die Daten endlich im physischen Speicher. Das Betriebssystem fragt die Seitentabelle erneut nach dem Tupel ab (4,3)
. Diesmal besagt die Seitentabelle, dass die Seite 4
bereits einem Frame 0
im RAM zugeordnet ist. Das Betriebssystem wechselt also einfach zum 0
dritten Frame im RAM und greift auf die versetzten Daten 3
in diesem Frame zu (nehmen Sie sich einen Moment Zeit, um dies zu verstehen. Das Ganzepage
, der von der Festplatte abgerufen wurde, wird nach verschoben frame
. Was auch immer der Versatz eines einzelnen Speicherplatzes auf einer Seite war, er ist auch im Frame derselbe, da sich die Speichereinheit innerhalb des page
/ frame
relativ immer noch an derselben Stelle befindet!) Und die Daten zurückgibt! Da die Daten bei der ersten Abfrage selbst nicht im Speicher gefunden wurden, sondern von der Festplatte abgerufen werden mussten, um in den Speicher geladen zu werden, handelt es sich um einen Fehler .
Fein. Angenommen, es wird ein Speicherzugriff für den Speicherort 28
vorgenommen. Es läuft darauf hinaus (3,4)
. Page table
Im Moment gibt es nur einen Eintrag, der die Seite 4
dem Frame zuordnet 0
. Dies ist also wieder ein Fehler , der Prozess gibt die CPU frei, der Gerätetreiber ruft die Seite von der Festplatte ab, der Prozess erlangt wieder die Kontrolle über die CPU und page table
wird aktualisiert. Angenommen, die Seite 3
ist jetzt dem Frame 1
im RAM zugeordnet. So (3,4)
wird (1,4)
, und die Daten an dieser Stelle im RAM werden zurückgegeben. Gut. Auf diese Weise nehme an, der nächste Speicherzugriff für die Lage ist 8
, was übersetzt (1,0)
. Die Seite 1
befindet sich noch nicht im Speicher, der gleiche Vorgang wird wiederholt und die page
wird im Frame zugewiesen2
im RAM. Jetzt sieht das RAM-Prozess-Mapping wie im obigen Bild aus. Zu diesem Zeitpunkt ist der RAM, für den nur 24 Speichereinheiten verfügbar waren, voll. Angenommen, die nächste Speicherzugriffsanforderung für diesen Prozess stammt von der Adresse 30
. Es (3,6)
wird zugeordnet und page table
sagt, dass sich die Seite 3
im RAM befindet, und es wird dem Frame zugeordnet 1
. Yay! Die Daten werden also vom RAM-Speicherort abgerufen (1,6)
und zurückgegeben. Dies stellt einen Treffer dar , da die erforderlichen Daten direkt aus dem RAM abgerufen werden können und somit sehr schnell sind. Ebenso sagen die nächsten Zugriffsanforderungen, für die Standorte 11
, 32
, 26
, 27
alle sind Treffer , dh durch den Prozess angeforderten Daten werden direkt im RAM gefunden , ohne an anderer Stelle suchen zu müssen.
Angenommen, es wird eine Speicherzugriffsanforderung für den Speicherort 3
gesendet. Es übersetzt in (0,3)
und page table
für diesen Prozess, der derzeit 3 Einträge für Seiten enthält 1
, 3
und 4
sagt, dass sich diese Seite nicht im Speicher befindet. Wie in früheren Fällen wird es von der Festplatte abgerufen, im Gegensatz zu früheren Fällen ist der Arbeitsspeicher jedoch voll! Was tun jetzt? Hier liegt die Schönheit des virtuellen Speichers, ein Frame aus dem RAM wird entfernt! (Verschiedene Faktoren bestimmen, welcher Frame entfernt werden soll. Es kann darauf LRU
basieren, wo der Frame, auf den zuletzt für einen Prozess zugegriffen wurde, entfernt werden soll. Es kann eine first-come-first-evicted
Basis sein, auf der der Frame, der vor langer Zeit zugewiesen wurde, entfernt wird usw. .) Also wird ein Rahmen entfernt. Sagen Sie Bild 1 (wählen Sie es einfach zufällig aus). Dies frame
ist jedoch einigen zugeordnetpage
! (Derzeit wird es von der Seitentabelle auf die Seite 3
unseres einzigen Prozesses abgebildet .) Dieser Prozess muss also über diese tragische Nachricht informiert werden, dass einer frame
, der Ihnen unglücklicherweise gehört, aus dem RAM entfernt werden soll, um Platz für einen anderen zu schaffen pages
. Der Prozess muss sicherstellen, dass er seine page table
Informationen mit diesen Informationen aktualisiert , dh den Eintrag für dieses Seitenrahmen-Duo entfernt, damit er page
dem Prozess bei der nächsten Anforderung mitteilt, dass sich dieser page
nicht mehr im Speicher befindet und muss von der Festplatte abgerufen werden. Gut. Der Frame 1
wird entfernt, die Seite 0
wird eingefügt und dort in den RAM gestellt, und der Eintrag für die Seite 3
wird entfernt und durch die 0
Zuordnung der Seite zu demselben Frame ersetzt1
. Jetzt sieht unser Mapping so aus (beachten Sie die Farbänderung in der zweiten frame
auf der rechten Seite):
Sah was gerade passiert ist? Der Prozess musste wachsen, er benötigte mehr Speicherplatz als der verfügbare RAM, aber im Gegensatz zu unserem früheren Szenario, in dem jeder Prozess im RAM verschoben werden musste, um einem wachsenden Prozess Rechnung zu tragen, geschah dies hier nur durch einen page
Austausch! Möglich wurde dies durch die Tatsache, dass der Speicher für einen Prozess nicht mehr zusammenhängend sein muss, sondern sich an verschiedenen Stellen in Blöcken befinden kann, das Betriebssystem die Informationen darüber verwaltet, wo sie sich befinden, und bei Bedarf entsprechend abgefragt wird. Hinweis: Sie denken vielleicht, was ist, wenn es sich meistens um eine miss
handelt und die Daten ständig von der Festplatte in den Speicher geladen werden müssen? Ja, theoretisch ist dies möglich, aber die meisten Compiler sind wie folgt konzipiertlocality of reference
Wenn also Daten von einem Speicherort verwendet werden, befinden sich die nächsten benötigten Daten an einem sehr nahe gelegenen Ort, möglicherweise von demselben page
, der page
gerade in den Speicher geladen wurde. Infolgedessen wird der nächste Fehler nach einiger Zeit auftreten. Die meisten anstehenden Speicheranforderungen werden von der gerade eingebrachten Seite oder den bereits im Speicher befindlichen Seiten erfüllt, die kürzlich verwendet wurden. Das exakt gleiche Prinzip ermöglicht es uns, auch das zuletzt verwendete zu entfernen page
, mit der Logik, dass das, was seit einiger Zeit nicht mehr verwendet wurde, wahrscheinlich auch nicht mehr verwendet wird. Dies ist jedoch nicht immer der Fall, und in Ausnahmefällen kann die Leistung darunter leiden. Dazu später mehr.
Lösung für Problem 4: Prozesse können jetzt problemlos wachsen. Wenn Platzprobleme auftreten, müssen Sie lediglich einen einfachen page
Austausch durchführen, ohne einen anderen Prozess zu verschieben.
Lösung zu Problem 1: Ein Prozess kann auf unbegrenzten Speicher zugreifen. Wenn mehr Speicher als verfügbar benötigt wird, wird die Festplatte als Sicherung verwendet, die neuen erforderlichen Daten werden von der Festplatte in den Speicher geladen und die zuletzt verwendeten Daten frame
(oder page
) werden auf die Festplatte verschoben. Dies kann unendlich weitergehen, und da der Speicherplatz billig und praktisch unbegrenzt ist, entsteht die Illusion von unbegrenztem Speicher. Ein weiterer Grund für den Namen Virtual Memory
ist die Illusion einer Erinnerung, die nicht wirklich verfügbar ist!
Cool. Früher hatten wir ein Problem, bei dem es schwierig ist, den leeren Raum von anderen Prozessen zurückzugewinnen, obwohl ein Prozess kleiner wird (da dies eine kostspielige Verdichtung erfordern würde). Wenn ein Prozess kleiner wird, ist es jetzt einfach, viele seiner pages
Prozesse werden nicht mehr verwendet. Wenn andere Prozesse mehr Speicher benötigen, werden durch eine einfache LRU
Räumung automatisch die weniger genutzten pages
aus dem RAM entfernt und durch die neuen Seiten von ersetzt die anderen Prozesse (und natürlich die Aktualisierung page tables
all dieser Prozesse sowie des ursprünglichen Prozesses, der jetzt weniger Platz benötigt), all dies ohne kostspielige Verdichtungsoperation!
Lösung für Problem 3: Wenn Prozesse kleiner werden, wird der frames
Arbeitsspeicher weniger verwendet, sodass LRU
diese Seiten durch eine einfache Räumung entfernt und pages
durch neue ersetzt werden können, wodurch sie Internal Fragmentation
ohne Notwendigkeit vermieden werden compaction
.
Nehmen Sie sich für Problem 2 einen Moment Zeit, um dies zu verstehen. Das Szenario selbst ist vollständig entfernt! Es ist nicht erforderlich, einen Prozess zu verschieben, um einen neuen Prozess aufzunehmen, da jetzt der gesamte Prozess nie mehr auf einmal passen muss, sondern nur bestimmte Seiten ad hoc passen müssen. Dies geschieht durch Entfernen frames
aus dem RAM. Alles geschieht in Einheiten von pages
, daher gibt es kein Konzept von hole
jetzt und daher keine Frage von irgendetwas, das sich bewegt! Möglicherweise mussten 10 pages
wegen dieser neuen Anforderung verschoben werden, von pages
denen Tausende unberührt bleiben. Während früher alle Prozesse (jedes Bit von ihnen) verschoben werden mussten!
Lösung zu Problem 2: Um einem neuen Prozess Rechnung zu tragen, müssen Daten von nur weniger kürzlich verwendeten Teilen anderer Prozesse nach Bedarf entfernt werden. Dies geschieht in Einheiten mit fester Größe, die aufgerufen werden pages
. Somit gibt es keine Möglichkeit für hole
oder External Fragmentation
mit diesem System.
Wenn der Prozess nun eine E / A-Operation ausführen muss, kann er die CPU leicht freigeben! Das Betriebssystem entfernt einfach alles pages
aus dem RAM (speichert es möglicherweise in einem Cache), während neue Prozesse in der Zwischenzeit den RAM belegen. Wenn die E / A-Operation abgeschlossen ist, stellt das Betriebssystem diese einfach pages
im RAM wieder her (natürlich durch Ersetzen der pages
von einigen anderen Prozessen, möglicherweise von denen, die den ursprünglichen Prozess ersetzt haben, oder von einigen, die selbst E / A ausführen müssen) O jetzt, und kann daher die Erinnerung aufgeben!)
Lösung zu Problem 5: Wenn ein Prozess E / A-Vorgänge ausführt, kann er leicht die RAM-Nutzung aufgeben, die von anderen Prozessen verwendet werden kann. Dies führt zu einer ordnungsgemäßen Auslastung des Arbeitsspeichers.
Und natürlich greift jetzt kein Prozess mehr direkt auf den RAM zu. Jeder Prozess greift auf einen virtuellen Speicherort zu, der einer physischen RAM-Adresse zugeordnet und page-table
von diesem Prozess verwaltet wird. Die Zuordnung ist vom Betriebssystem unterstützt. Das Betriebssystem teilt dem Prozess mit, welcher Frame leer ist, sodass dort eine neue Seite für einen Prozess angepasst werden kann. Da diese Speicherzuweisung vom Betriebssystem selbst überwacht wird, kann leicht sichergestellt werden, dass kein Prozess in den Inhalt eines anderen Prozesses eingreift, indem nur leere Frames aus dem RAM zugewiesen werden oder wenn in den Inhalt eines anderen Prozesses im RAM eingegriffen wird, mit dem Prozess kommuniziert wird um es zu aktualisieren page-table
.
Lösung für das ursprüngliche Problem: Es besteht keine Möglichkeit, dass ein Prozess auf den Inhalt eines anderen Prozesses zugreift, da die gesamte Zuordnung vom Betriebssystem selbst verwaltet wird und jeder Prozess in einem eigenen virtuellen Adressraum mit Sandbox ausgeführt wird.
So paging
(unter anderen Techniken), in Verbindung mit dem virtuellen Speichern, ist die heutige , welche Kräfte Software läuft auf O-es! Dies befreit den Softwareentwickler von der Sorge, wie viel Speicher auf dem Gerät des Benutzers verfügbar ist, wo die Daten gespeichert werden sollen, wie verhindert werden kann, dass andere Prozesse die Daten seiner Software beschädigen usw. Dies ist jedoch natürlich nicht vollständig sicher. Es gibt Mängel:
Paging
gibt dem Benutzer letztendlich die Illusion eines unendlichen Speichers, indem er die Festplatte als sekundäres Backup verwendet. Das Abrufen von Daten aus dem Sekundärspeicher, um in den Speicher zu passen (aufgerufen page swap
, und der Fall, dass die gewünschte Seite im RAM nicht gefunden wird, wird aufgerufen page fault
) ist teuer, da es sich um eine E / A-Operation handelt. Dies verlangsamt den Prozess. Mehrere solcher Seitentauschvorgänge finden nacheinander statt, und der Vorgang wird schmerzhaft langsam. Haben Sie jemals gesehen, dass Ihre Software einwandfrei läuft und plötzlich so langsam wird, dass sie fast hängt, oder Sie haben keine andere Möglichkeit, sie neu zu starten? Möglicherweise wurden zu viele Seitentauschvorgänge durchgeführt, wodurch es langsam wurde (aufgerufen thrashing
).
Also zurück zu OP,
Warum benötigen wir den virtuellen Speicher zum Ausführen eines Prozesses? - Wie die Antwort ausführlich erklärt, um Software die Illusion zu vermitteln, dass das Gerät / Betriebssystem über unendlichen Speicher verfügt, sodass jede große oder kleine Software ausgeführt werden kann, ohne sich Gedanken über die Speicherzuweisung oder andere Prozesse zu machen, die ihre Daten beschädigen, selbst wenn parallel laufen. Es ist ein Konzept, das in der Praxis durch verschiedene Techniken umgesetzt wird, von denen eine, wie hier beschrieben, Paging ist . Es kann auch Segmentierung sein .
Wo steht dieser virtuelle Speicher, wenn der Prozess (Programm) von der externen Festplatte zur Ausführung in den Hauptspeicher (physischen Speicher) gebracht wird? - Der virtuelle Speicher steht an sich nirgendwo, er ist eine Abstraktion, die immer vorhanden ist, wenn die Software / der Prozess / das Programm gestartet wird, eine neue Seitentabelle dafür erstellt wird und die Zuordnung der von ihr ausgespuckten Adressen enthält Prozess zur tatsächlichen physischen Adresse im RAM. Da die durch den Prozess ausgespuckten Adressen in gewissem Sinne keine echten Adressen sind, sind sie tatsächlich das, was Sie sagen können the virtual memory
.
Wer kümmert sich um den virtuellen Speicher und wie groß ist der virtuelle Speicher? - Es wird gemeinsam vom Betriebssystem und der Software erledigt. Stellen Sie sich eine Funktion in Ihrem Code vor (die schließlich kompiliert und in die ausführbare Datei umgewandelt wurde, die den Prozess ausgelöst hat), die eine lokale Variable enthält - eine int i
. Wenn der Code ausgeführt wird, i
wird eine Speicheradresse im Stapel der Funktion abgerufen. Diese Funktion wird selbst als Objekt an einem anderen Ort gespeichert. Diese Adressen werden vom Compiler generiert (der Compiler, der Ihren Code in die ausführbare Datei kompiliert hat) - virtuelle Adressen. Wenn es ausgeführt wird, i
muss es sich mindestens für die Dauer dieser Funktion irgendwo in der tatsächlichen physischen Adresse befinden (es sei denn, es ist eine statische Variable!), Damit das Betriebssystem die vom Compiler generierte virtuelle Adresse von abbildeti
in eine tatsächliche physische Adresse, so dass i
dieser Prozess , wenn innerhalb dieser Funktion ein Code den Wert von benötigt , das Betriebssystem nach dieser virtuellen Adresse abfragen kann und das Betriebssystem wiederum die physische Adresse nach dem gespeicherten Wert abfragen und zurückgeben kann.
Angenommen, die Größe des Arbeitsspeichers beträgt 4 GB (dh 2 ^ 32-1 Adressräume). Wie groß ist der virtuelle Speicher? - Die Größe des Arbeitsspeichers hängt nicht von der Größe des virtuellen Speichers ab, sondern vom Betriebssystem. Unter 32-Bit-Windows ist dies beispielsweise 16 TB
unter 64-Bit-Windows der Fall 256 TB
. Natürlich ist es auch durch die Festplattengröße begrenzt, da dort der Speicher gesichert wird.