Laut Windows ist der Arbeitsspeicher aufgebraucht, obwohl noch 4 GB physischer Speicher verfügbar sind

24

Screenshot der Systeminformationen aus Process Explorer

Diese Systeminformationen stammen aus dem Process Explorer. Es ist noch physischer Speicher verfügbar, aber das System zeigt fast keinen Arbeitsspeicher mehr an.

Der Task-Manager zeigt auch, dass etwa 74% des gesamten Arbeitsspeichers verwendet werden.

Seit der Installation von Windows 8.1 verfügte der Computer über 4 + 8 = 12 GB RAM. Ich habe es aktualisiert, indem ich die 4 GB in ein 8 GB-Modul geändert habe. Könnte das das Problem sein? Oder ist dieses Verhalten normal und ich habe gerade die Bedeutung des verfügbaren physischen Speichers falsch verstanden?

user471487
quelle
Das Bild, das er anhängen wollte, ist hier: tinypic.com/view.php?pic=npon5c&s=8#.Va3P3_lVhBc Ich habe einer Bearbeitung zum Hinzufügen dieser URL zugestimmt, aber das reicht anscheinend nicht aus.
Jamie Hanrahan
@JamieHanrahan: Bilder sollten über die Ctrl+GVerknüpfung hochgeladen werden, damit Stack Exchange sie im Laufe der Zeit vor dem Verrotten schützt .
Deltik
@ Deltik Es war nicht mein Bild zum Hochladen.
Jamie Hanrahan
@JamieHanrahan - Nachdem die Frage eingereicht wurde, wurde dem Material eine Lizenz zugewiesen, das Bild ist die Community zu diesem Zeitpunkt ..
Ramhound
Zum späteren Nachschlagen notiert, danke. Ich habe in einer vorgeschlagenen Bearbeitung einfach den Link zur Tinypic-Site gesehen und diese Bearbeitung genehmigt, aber das hatte keine Auswirkung.
Jamie Hanrahan

Antworten:

65

Kurze Antwort

Das Popup-Fenster "Nicht genügend Arbeitsspeicher" zeigt an, dass der private festgeschriebene Arbeitsspeicher - eine Art virtueller Arbeitsspeicher - nicht mehr ausreicht . Nicht, dass Ihnen der Arbeitsspeicher (der physische Speicher) ausgeht. Es spielt keine Rolle , wie viel verfügbar RAM Sie haben. Wenn Sie über viel verfügbaren RAM verfügen, können Sie das Festschreibungslimit nicht überschreiten. Das Commit-Limit ist die Summe Ihres gesamten RAM (egal ob in Verwendung oder nicht!) Plus Ihrer aktuellen Auslagerungsdatei.

Umgekehrt verbraucht das Commit-Limit "verbraucht" (das meistens die Erstellung eines prozessprivaten virtuellen Adressraums ist) nicht unbedingt RAM! Das Betriebssystem lässt seine Erstellung jedoch erst zu, wenn es weiß, dass es einen Speicherplatz gibt, falls dies jemals erforderlich ist. So können Sie das Festschreibungslimit erreichen, ohne den gesamten RAM oder sogar den größten Teil des RAM zu verwenden.

Aus diesem Grund sollten Sie nicht ohne eine Auslagerungsdatei ausführen. Beachten Sie, dass die Auslagerungsdatei möglicherweise nie tatsächlich beschrieben wird! Sie können jedoch trotzdem die Fehler "Wenig Arbeitsspeicher" und "Nicht genügend Arbeitsspeicher" vermeiden.

Zwischenantwort

Windows hat keine Fehlermeldung, wenn der Arbeitsspeicher knapp wird. Was Ihnen ausgeht, ist "Festschreibungslimit".

Das "System" -Diagramm in dieser Version von Process Explorer hat einen schlechten Namen. Es sollte mit "Festschreibegebühr" gekennzeichnet sein. (In der Version, die ich habe, heißt es "System-Commit". Besser, aber immer noch nicht vollständig konsistent.) In jedem Fall wird die "aktuelle" Höhe des Diagramms weiter unten im Textabschnitt als "Commit Charge" - "angezeigt. Current ", und die maximale Höhe des Graphen steht für" Commit Charge "-" Limit ".

"Festschreibegebühr" bezieht sich auf den virtuellen Adressraum, der von der Auslagerungsdatei (falls vorhanden) gesichert wird. Mit anderen Worten, wenn nicht alle in den Arbeitsspeicher passen, wird der Rest in die Auslagerungsdatei geschrieben. (Es gibt andere Arten von Vas, die entweder von anderen Dateien unterstützt werden - die als "zugeordnete" Vas bezeichnet werden - oder die die ganze Zeit im RAM verbleiben müssen. Letztere werden als "nicht auslagerbar" bezeichnet.) Die "Festschreibungsgrenze" ist das Maximum dafür die "Festschreibegebühr" kann sein. Es entspricht Ihrer RAM-Größe plus der Größe der Auslagerungsdatei.

Sie haben anscheinend keine Auslagerungsdatei (ich kann sagen, weil Ihr Festschreibungslimit Ihrer RAM-Größe entspricht), also ist das Festschreibungslimit einfach die RAM-Größe.

Anscheinend haben verschiedene Programme + das Betriebssystem fast alle maximal möglichen Commits verwendet.

Dies hat nichts direkt damit zu tun, wie viel RAM frei oder verfügbar ist. Ja, Sie haben ungefähr 4,5 GB RAM zur Verfügung. Das bedeutet nicht, dass Sie das Festschreibungslimit überschreiten können. Der festgeschriebene Speicher benötigt nicht unbedingt RAM und ist nicht durch die Größe des verfügbaren RAM begrenzt.

Sie müssen entweder die Auslagerungsdatei erneut aktivieren - bei dieser Menge an Commit würde ich eine 16-GB-Auslagerungsdatei vorschlagen, da Sie das Betriebssystem nicht zwingen möchten, so viel davon im RAM zu belassen, und die Auslagerungsdatei funktioniert am besten, wenn dies der Fall ist hat viel freien Platz - oder füge mehr RAM hinzu. Eine Menge mehr. Für eine gute Leistung muss im RAM ausreichend Platz für Code und andere Elemente vorhanden sein, die nicht von der Auslagerungsdatei unterstützt werden (sondern in andere Dateien ausgelagert werden können).

Sehr lange Antwort

(aber immer noch viel kürzer als das Speicherverwaltungskapitel von Windows Internals ...)

Angenommen, ein Programm weist 100 MB prozessprivaten virtuellen Speicher zu. Dies geschieht mit einem VirtualAlloc-Aufruf mit der Option "commit". Dies führt zu einer Erhöhung der "Commit-Gebühr" um 100 MB. Diese "Zuordnung" belegt aber eigentlich keinen RAM! RAM wird nur verwendet, wenn zum ersten Mal auf einen Teil des neu festgeschriebenen virtuellen Adressraums zugegriffen wird.

Wie der RAM letztendlich genutzt wird

(wenn es jemals tut)

Der erstmalige Zugriff auf den neu zugewiesenen Speicherplatz würde fast immer ein Speicherschreiben sein (das Lesen neu zugewiesener privater Speicherplätze vor dem Schreiben ist fast immer ein Programmierfehler, da sein anfänglicher Inhalt streng genommen undefiniert ist). Beim Lesen oder Schreiben ist das Ergebnis, wenn Sie zum ersten Mal eine Seite mit neu zugewiesenen Vas berühren, ein Seitenfehler . Obwohl das Wort "Fehler" schlecht klingt, sind Seitenfehler ein vollständig erwartetes und sogar erforderliches Ereignis in einem virtuellen Speicherbetriebssystem.

In Reaktion auf diesen speziellen Seitenfehlertyp führt der Pager (Teil des Speichermanagers des Betriebssystems, der manchmal mit "Mm" abgekürzt wird) Folgendes aus:

  1. Zuweisen einer physischen Seite des Arbeitsspeichers (idealerweise aus der Liste der Nullseiten, aber auf jeden Fall aus dem, was Windows als "verfügbar" bezeichnet: Die Liste der Nullseiten, der freien Seiten oder der Standby-Seiten in dieser Reihenfolge);
  2. Füllen Sie einen Seitentabelleneintrag aus, um die physische Seite mit der virtuellen Seite zu verknüpfen. und schlussendlich
  3. Die Ausnahmebedingung "Seitenfehler" verwerfen.

Danach führt der Code, der die Speicherreferenz erstellt hat, den Befehl, der den Seitenfehler ausgelöst hat, erneut aus. Diesmal ist die Referenz erfolgreich.

Wir sagen, dass die Seite im Prozess-Arbeitssatz und im RAM "fehlerhaft" ist. Im Task-Manager wird dies als eine einseitige Erhöhung (4 KB) im "privaten Arbeitssatz" des Prozesses angezeigt. Und eine Reduzierung des verfügbaren physischen Speichers um eine Seite. (Letzteres ist auf einem stark ausgelasteten Computer möglicherweise schwer zu bemerken.)

Hinweis 1: Bei diesem Seitenfehler wurde nichts von der Festplatte gelesen. Eine Seite mit festgeschriebenem virtuellen Speicher, auf die noch nie zuvor zugegriffen wurde, beginnt nicht auf der Festplatte zu laufen. es hat keinen Platz auf der Festplatte , es zu lesen aus . Es wird einfach in einer zuvor verfügbaren Seite des RAM "materialisiert". Statistisch gesehen werden die meisten Seitenfehler im RAM behoben, entweder in gemeinsam genutzten Seiten, die sich bereits für andere Prozesse im RAM befinden, oder in den Seiten-Caches - den Standby- oder geänderten Listen - oder als "Demand Zero" -Seiten wie diese.

Hinweis 2: Dies dauert nur eine Seite, 4096 Bytes, von "Verfügbar". Der zuvor noch nie berührte festgeschriebene Adressraum wird normalerweise nur seitenweise erkannt (fehlerhaft), da jede Seite zum ersten Mal "berührt" wird. Es würde keine Besserung und keinen Vorteil bringen, mehr auf einmal zu tun. es würde nur n mal so lange dauern. Im Gegensatz dazu wird beim Lesen von Seiten von der Festplatte ein gewisser "Readahead" -Versuch unternommen, da der Großteil der Zeit beim Lesen der Festplatte auf die einzelnen Vorgänge entfällt und nicht auf die eigentliche Datenübertragung. Die Menge "gebunden" bleibt bei 100 MB; Die Tatsache, dass eine oder mehrere Seiten fehlerhaft sind, reduziert die Bereitstellungsgebühr nicht.

Notiz 3:Nehmen wir an, wir haben 4 GB "verfügbaren" RAM. Dies bedeutet, dass wir auf bereits zugewiesenen, aber noch nie zuvor referenzierten festgeschriebenen Speicher ungefähr eine Million Mal mehr verweisen können (4 GB / 4096), bevor uns der Arbeitsspeicher ausgeht. Wenn wir eine Auslagerungsdatei haben, wie es David Cutler und Lou Perazzoli beabsichtigt haben, werden einige der Seiten, auf die vor langer Zeit im RAM verwiesen wurde, auf der Festplatte gespeichert und dann zur Behebung dieser neueren Seitenfehler verfügbar gemacht. (Tatsächlich würde das Betriebssystem RAM-Rückgewinnungsmethoden wie "Working Set Trimming" eher vorher einleiten, und die tatsächlichen Schreibvorgänge in die Auslagerungsdatei werden aus Effizienzgründen in der modifizierten Seitenliste zwischengespeichert und gestapelt, und ...) "engagiert" zählen. Dies ist jedoch für das "Festschreibungslimit" relevant. Wenn nicht Platz für alle ist "

Und es passiert immer wieder ...

Aber nehmen wir an, wir haben nicht mehr als eine Million Referenzen erstellt und es sind immer noch Seiten im Wert von 4 GB "verfügbar". Nehmen wir nun an, dass derselbe Prozess - oder ein anderer, spielt keine Rolle - einen anderen VirtualAlloc ausführt, diesmal mit 200 MB Commit. Auch diese 200 MB werden zur Festschreibegebühr hinzugefügt, und es wird kein RAM aus dem verfügbaren Speicher entfernt. Durch einfaches Zuweisen des Adressraums zu VirtualAlloc wird nicht die entsprechende Menge an RAM verbraucht, und ein niedriger "verfügbarer" RAM begrenzt nicht die Menge an Adressraum, die Sie zu VirtualAlloc hinzufügen können (und ein hoher verfügbarer RAM erhöht ihn auch nicht).

(Nun, ok ... es gibt ein kleines bisschen Overhead, das einer (auslagerbaren!) Seite entspricht, die für eine Seitentabelle für jeweils 2 MB (4 MB, wenn Sie sich in einem x86-System ohne PAE befinden) von verwendet wird zugewiesener virtueller Adressraum, und es gibt einen "virtuellen Adressdeskriptor" von einigen zehn Bytes für jeden virtuell zusammenhängenden zugewiesenen Bereich.)

Auf diese Weise ist es möglich - und üblich! - viel "Commit Charge" verbrauchen und dabei nur wenig RAM verbrauchen.

Wenn das "Festschreiben" des virtuellen Adressraums nicht den Arbeitsspeicher belegt, warum muss es dann ein Limit geben?

Weil die "Festschreibegebühr" die potenzielle zukünftige Nutzung von Speicherplatz darstellt. "Festschreibungslimit" gibt die Gesamtmenge an Speicher (RAM + Seitendateispeicher) an, die verfügbar ist, um solche Zuordnungen zu speichern , falls sie jemals tatsächlich referenziert werden und von dort irgendwo gespeichert werden müssen.

Wenn der Mm eine VirtualAlloc-Anforderung genehmigt, ist es vielversprechend - "eine Verpflichtung eingehen" -, dass alle nachfolgenden Speicherzugriffe auf den zugewiesenen Bereich erfolgreich sein werden; Sie können zu Seitenfehlern führen, aber die Fehler können alle behoben werden, da genügend Speicher vorhanden ist, um den Inhalt aller dieser Seiten im RAM oder in der Auslagerungsdatei zu speichern. Der Mm weiß dies, weil er weiß, wie viel Speicherplatz vorhanden ist (das Festschreibungslimit) und wie viel bereits "festgeschrieben" wurde (die aktuelle Festschreibungsgebühr).

(Da jedoch noch nicht unbedingt auf alle Seiten zugegriffen wurde, ist zu jedem Zeitpunkt nicht unbedingt ein Speicherplatz verfügbar, der dem zugesagten Betrag entspricht.)

Also ... Was ist mit "System hat nicht genügend Speicher"?

Wenn Sie versuchen, VirtualAlloc zu verwenden, überschreitet die aktuelle Festschreibegebühr plus die angeforderte Zuordnungsgröße das Festschreibungslimit, UND das Betriebssystem kann die Auslagerungsdatei nicht erweitern, um das Festschreibungslimit zu erhöhen. und der Prozess sieht den VirtualAlloc-Aufruf FAIL. Die meisten Programme werfen nur die Hände hoch und sterben an diesem Punkt. Einige werden blindlings weitermachen, wenn der Anruf erfolgreich war, und später scheitern, wenn sie versuchen, auf die Region zu verweisen, von der sie dachten, dass sie sie zugewiesen haben.

Nochmals (Entschuldigung für die Wiederholung): Es spielt keine Rolle, wie viel RAM Sie zur Verfügung haben. Das Betriebssystem hat versprochen , dass der RAM oder Auslagerungsdatei Raum wird zur Verfügung, wenn sie gebraucht wird , aber das Versprechen subtrahiert nicht von „verfügbar“. Verfügbar RAM wird nur von engagiertem vm verbraucht , wenn es referenziert zum ersten Mal, das ist das, was bewirkt , dass es „bemängelte in“ ... dh im physischen Speicher realisiert werden. Und das einfache Festschreiben (= Zuweisen) von virtuellem Speicher reicht nicht aus. Es nimmt nur freien virtuellen Adressraum in Anspruch und macht daraus nutzbaren virtuellen Adressraum.

Im Fall von "Nicht genügend Arbeitsspeicher" gab es eine Zuweisungsanforderung für festgeschriebenen Arbeitsspeicher, und das Betriebssystem hat die aktuelle Festschreibungsgebühr zur Größe dieser neuen Anforderung hinzugefügt ... und festgestellt, dass die Summe mehr als das Festschreibungslimit ist . Wenn also das Betriebssystem diese neue Version genehmigt und der gesamte Speicherplatz danach referenziert würde, gäbe es keine realen Speicherplätze (RAM + Auslagerungsdatei), um alles zu speichern.

Das Betriebssystem lässt dies nicht zu. Im schlimmsten Fall können nicht mehr Vas zugewiesen werden, als Speicherplatz zur Verfügung steht - auch wenn alle "fehlerhaft" sind. Das ist der Zweck des "Commit-Limits".

Ich sage es dir dreimal Ich sage es dir dreimal Ich sage es dir dreimal: Die Größe des "verfügbaren" RAM spielt keine Rolle. Dass der festgeschriebene virtuelle Speicherplatz noch nicht den gesamten Speicherplatz belegt, spielt keine Rolle. Windows kann keine "Festschreibung" für die virtuelle Zuordnung vornehmen, es sei denn, es kann in Zukunft ein Fehler auftreten.

Beachten Sie, dass es eine andere Art von vas gibt, die als "zugeordnet" bezeichnet wird und hauptsächlich für Code und den Zugriff auf große Datendateien verwendet wird. Sie wird jedoch nicht als "Festschreibungsgebühr" berechnet und ist nicht durch das "Festschreibungslimit" begrenzt. Dies liegt daran, dass es einen eigenen Speicherbereich hat, die Dateien, die ihm "zugeordnet" sind. Die einzige Beschränkung für "zugeordnete" Vas ist die Menge an Festplattenspeicher, die Sie für die zugeordneten Dateien haben, und die Menge an freien Vas in Ihrem Prozess, denen Sie sie zuordnen können.

Aber wenn ich mir das System anschaue, bin ich noch nicht ganz am Commit-Limit?

Das ist im Grunde genommen ein Problem bei der Messung und Aufzeichnung. Sie sehen das System, nachdem ein VirtualAlloc-Aufruf bereits versucht wurde und fehlgeschlagen ist.

Angenommen, Sie haben nur noch ein Commit-Limit von 500 MB und ein Programm hat versucht, VirtualAlloc mit 600 MB zu betreiben. Der Versuch schlägt fehl. Dann schauen Sie sich das System an und sagen: "Was? Es sind noch 500 MB übrig!" Tatsächlich könnte bis dahin noch viel mehr übrig sein, da der fragliche Prozess wahrscheinlich zu diesem Zeitpunkt vollständig abgeschlossen ist, sodass der gesamte zuvor zugewiesene festgeschriebene Speicher freigegeben wurde.

Das Problem ist , dass Sie nicht in der Zeit zurückblicken und sehen , was die commit Ladung war im Moment Versuch der alloc gemacht wurde. Und Sie wissen auch nicht, für wie viel Platz der Versuch war. Sie können also nicht definitiv erkennen, warum der Versuch fehlgeschlagen ist oder wie viel mehr "Festschreibungslimit" erforderlich gewesen wäre, damit er funktioniert.

Ich habe gesehen, "System hat wenig Speicher". Was ist das?

Wenn im obigen Fall das Betriebssystem die Auslagerungsdatei erweitern kann (dh wenn Sie die Standardeinstellung "System verwaltet" beibehalten oder das Maximum auf einen höheren Wert als den ursprünglichen Wert festlegen und genügend freier Speicherplatz vorhanden ist) und Durch eine solche Erweiterung wird das Festschreibungslimit ausreichend erhöht, damit der VirtualAlloc-Aufruf erfolgreich ausgeführt werden kann. Anschließend wird die Auslagerungsdatei vom Mm erweitert, und der VirtualAlloc-Aufruf wird erfolgreich ausgeführt.

Und das ist, wenn Sie sehen, "System läuft auf Speicher LOW". Dies ist eine frühe Warnung, dass, wenn die Dinge ohne Schadensbegrenzung weitergehen, Sie wahrscheinlich bald eine Warnung "Nicht genügend Speicher" sehen. Es ist Zeit, einige Apps zu schließen. Ich würde mit Ihrem Browserfenster beginnen.

Und du denkst, das ist eine gute Sache? Die Erweiterung der Auslagerungsdatei ist böse !!!

Nein, das ist es nicht. Das Betriebssystem "erweitert" die vorhandene Datei nicht wirklich. Es wird nur ein neuer Bereich zugewiesen. Der Effekt ist mit jeder anderen nicht zusammenhängenden Datei vergleichbar. Der Inhalt der alten Auslagerungsdatei bleibt dort, wo er ist. Sie müssen nicht an einen anderen Ort kopiert werden. Da die meisten Auslagerungsdateien im Vergleich zur Größe der Auslagerungsdateien relativ klein sind, ist die Wahrscheinlichkeit, dass eine bestimmte Übertragung eine Ausdehnungsgrenze überschreitet, sehr gering. Daher schadet die Fragmentierung nur, wenn sie wirklich übermäßig groß ist.

Wenn alle Prozesse, für die Speicherplatz in der Erweiterung "festgeschrieben" wurde, beendet wurden (beim Herunterfahren des Betriebssystems, wenn nicht früher), werden die Speicherbereiche unbeaufsichtigt freigegeben, und die Auslagerungsdatei wird auf die vorherige Größe und Zuordnung zurückgesetzt - sofern sie zuvor zusammenhängend war ist so wieder.

Das Ermöglichen der Erweiterung von Auslagerungsdateien wirkt daher als ein völlig freies Sicherheitsnetz: Wenn Sie dies zulassen, das System es jedoch niemals benötigt, wird das System die Auslagerungsdatei nicht "ständig erweitern und verkleinern", wie oft behauptet wird, so dass es nichts kostet . Und wenn Sie es jemals brauchen, werden Sie vor Apps bewahrt, die mit Fehlern "Nicht genügend virtueller Speicher" abstürzen.

Aber, aber, aber...

Ich habe auf Dutzenden von Websites gelesen, dass Windows die Auslagerungsdatei ständig erweitert und verkleinert, wenn Sie die Auslagerungsdatei erweitern, und dass dies zu einer Fragmentierung der Auslagerungsdatei führt, bis Sie sie defragmentieren.

Sie liegen einfach falsch.

Wenn Sie noch nie das Popup "Wenig Speicher" (oder in älteren Versionen "Wenig virtueller Speicher") gesehen haben, hat das Betriebssystem Ihre Auslagerungsdatei noch nie erweitert.

Wenn Sie dieses Popup sehen, wird Ihnen mitgeteilt, dass Ihre anfängliche Auslagerungsdatei zu klein ist. (Ich möchte es auf ungefähr das 4-fache der maximal beobachteten Auslastung einstellen, dh der Leistungsindikator "% pagefile usage peak" sollte unter 25% liegen. Grund: Der Auslagerungsspeicher wird wie jeder andere Heap verwaltet und funktioniert am besten mit viel freiem Speicherplatz zum spielen.)

Aber warum nicht einfach ...

Man könnte argumentieren, dass das Betriebssystem nur die Zuordnung zulassen und dann die Verweise fehlschlagen lassen sollte, wenn kein RAM verfügbar ist, um die Seitenfehler zu beheben. Mit anderen Worten, weiter oben wurde beschrieben, wie der anfängliche Seitenfehler funktioniert. Was wäre, wenn "Zuweisen einer verfügbaren physischen RAM-Seite" (Schritt 1) ​​nicht möglich wäre, da keine verfügbar wäre und kein Platz vorhanden wäre Links, um etwas herauszublättern, um etwas zur Verfügung zu stellen?

Dann kann der Pager den Seitenfehler nicht beheben. Es müsste möglich sein, dass die Ausnahme (der Seitenfehler) an den fehlerhaften Thread zurückgemeldet wird, wahrscheinlich in einen anderen Ausnahmecode geändert.

Die Entwurfsphilosophie ist, dass VirtualAlloc Null (technisch gesehen ein NULL-Zeiger) anstelle einer Adresse zurückgibt, wenn das Festschreibungslimit überschritten wird, und es ist durchaus vernünftig zu erwarten, dass der Programmierer weiß, dass ein VirtualAlloc-Aufruf fehlschlagen kann. Von Programmierern wird daher erwartet, dass sie nach diesem Fall suchen und eine angemessene Antwort geben (z. B. die Möglichkeit, Ihre Arbeit bis zu diesem Zeitpunkt zu speichern und das Programm dann "ordnungsgemäß" zu beenden). (Programmierer: Sie suchen nach einer NULL-Zeiger-Rückkehr von malloc, new usw., ja? Warum sollten Sie das dann nicht tun?)

Aber Programmierer sollten nicht damit rechnen müssen, dass eine einfache Speicherreferenz gefällt

i = 0;             // initialize loop counter

schlägt möglicherweise fehl - nicht, wenn es sich um eine Region mit erfolgreich zugesichertem Adressraum handelt. (Oder zugeordneten Adressraum für diese Angelegenheit.) Aber das ist, was passieren könnte, wenn die Philosophie "die übergebene Zuweisung zulassen, die Speicherreferenz fehlschlagen lassen" befolgt wurde.

Leider bietet eine Speicherreferenz wie die in der obigen Codezeile keine bequeme Möglichkeit, einen schlechten Status zurückzugeben! Sie sollen nur funktionieren , genau wie Addition und Subtraktion. Die einzige Möglichkeit, solche Fehler zu melden, wären Ausnahmen. Um mit ihnen umgehen zu können, müsste der Programmierer das gesamte Programm in einen Exception-Handler einbinden. (versuchen ... fangen und das alles.)

Das kann getan werden ... Aber es wäre schwierig für den Handler, zu wissen, wie er als Reaktion auf diese Ausnahmen "das Richtige tut", da es so viele, viele Punkte im Code geben würde, an denen sie entstehen könnten. (Insbesondere können sie bei jeder Speicherreferenz auf VirtualAlloc'd-Speicher, auf Speicher, der mit malloc oder new zugewiesen wurde, und auch auf alle lokalen Variablen auftreten, da der Stack ebenfalls VirtualAlloc'd ist.)

Kurz gesagt, es wäre sehr schwierig, das Programm in diesen Fällen ordnungsgemäß zum Scheitern zu bringen.

Auf der anderen Seite ist es ziemlich einfach, nach einer NULL-Pointer-Rückkehr von VirtualAlloc (oder malloc oder new, obwohl sie nicht genau dasselbe sind) zu suchen und dann etwas Vernünftiges zu tun ... wie nicht zu versuchen auf und mach, was immer es war, das Programm brauchte den virtuellen Raum für. Und vielleicht fragen Sie den Benutzer, ob er seine Arbeit soweit speichern möchte. (Zugegeben, viel zu viele Apps machen sich nicht die Mühe, auch nur so viel zu machen.)

Andere Benutzer von commit

Im Übrigen wird das "Festschreibungslimit" nicht durch die verschiedenen Zuordnungen des Betriebssystems wie den ausgelagerten und nicht ausgelagerten Pool, die PFN-Liste usw .; Diese werden nur berechnet, um eine Gebühr zu erheben, sobald sie anfallen. Die Commit-Gebühr oder das Commit-Limit werden auch nicht durch die Größe des Video-RAM oder sogar des Video-RAM-Fensters beeinflusst.

Testen Sie es selbst

All dies können Sie mit dem Testlimit-Tool von der SysInternals-Site testen. Option -m weist den festgeschriebenen Adressraum zu, "berührt" ihn jedoch nicht und bewirkt daher keine Zuweisung von RAM. Während Option -d die Seiten zuordnet und auch referenziert, werden sowohl die Commit-Gebühren erhöht als auch der verfügbare RAM verringert.

Verweise

Windows Internals von Russinovich, Solomon und Ionescu. Es gibt sogar Demonstrationen, mit denen Sie all diese Punkte mit dem Testlimit-Tool beweisen können. Ich muss Sie jedoch warnen, dass Sie gewarnt sein sollten, wenn Sie der Meinung sind, dass dies lang ist: Das Mm-Kapitel allein umfasst 200 Seiten. Das Obige ist eine EXTREM vereinfachte Version. (Bitte beachten Sie auch den Abschnitt "Danksagungen" in der Einleitung.)

Siehe auch MSDN VirtualAlloc-Dokumentation

Jamie Hanrahan
quelle
4
@AcePL Ich habe erklärt, warum. Kurz gesagt: Es passiert, weil sein Commit-Limit für seine Arbeitslast zu niedrig ist. Das Commit-Limit ist die Gesamtgröße des Arbeitsspeichers + die aktuelle Auslagerungsdatei. Die Menge an "verfügbarem" RAM wird nicht eingegeben. Der "Festschreibungslimit" -Mechanismus erlaubt keine Zuweisung von virtuellem Adressraum über die Verfügbarkeit von physischem Speicher (RAM + Sicherungsspeicher auf der Festplatte, dh Auslagerungsdatei) hinaus, um das Zeug zu behalten. Denken Sie daran, auch wenn es virtuell ist, muss es irgendwo aufbewahrt werden, wenn es zum ersten Mal fehlerhaft ist.
Jamie Hanrahan
5
@AcePL - Dem Benutzer geht nicht der Speicherplatz aus. Ihm geht der virtuelle Speicher aus. Diese Erklärung ist zu 100% gültig.
Ramhound
1
@ Rahul Basu Eigentlich würde ich erwarten, dass der kurze Kommentar viel schwieriger zu verstehen ist. ;) Diese und viele ähnliche Fragen sind ein Beweis dafür, dass viele Menschen ein tiefes Missverständnis über virtuellen Speicher, Adressräume, Arbeitssätze usw. haben. Nicht ihre Schuld - es ist ein sehr komplexes Thema, und die Anzeigen von MS waren noch nie so klar wie sie sein könnten . Aber es braucht viele Worte, um auch nur einen Teil davon zu erklären. Die Windows-Interna haben Diagramme, die helfen. Animierte Diagramme wären noch besser ...
Jamie Hanrahan
3
Möglicherweise von Interesse: "Lassen Sie die Zuweisung einfach geschehen und lassen Sie die Referenzen dann fehlschlagen, wenn kein RAM verfügbar ist, um die Seitenfehler zu beheben." Der virtuelle Speicher für schmutzige Seiten wird knapp, und dann setzt der Killer für unzureichenden Speicher ein ... und beendet einen möglicherweise völlig unabhängigen Prozess . Ja, böse.
Bob
1
@ Jamie Hanrahan Sieht so aus, als hättest du es bereits getan (sorry, war etwas beschäftigt). Ja, Overcommit ist konfigurierbar und wird von einigen Distributionen deaktiviert. Aber es sieht so aus, als ob es in den Jahren 2013 und 2014 noch immer üblich war , und ich glaube, es ist die Kernel-Standardeinstellung, wenn sie nicht explizit festgelegt wurde (von der Distribution oder vom Benutzer).
Bob