
Diese Systeminformationen stammen aus dem Process Explorer. Es ist noch physischer Speicher verfügbar, aber das System zeigt an, dass fast kein RAM mehr übrig ist.
Der Task-Manager zeigt außerdem, dass etwa 74 % des gesamten RAM verwendet werden.
Seit der Installation von Windows 8.1 verfügte der Computer über 4+8=12 GB RAM. Ich habe ihn aufgerüstet, indem ich das 4 GB-Modul gegen ein 8 GB-Modul ausgetauscht habe. Könnte das das Problem sein? Oder ist dieses Verhalten normal und ich habe einfach die Bedeutung des verfügbaren physischen Speichers falsch verstanden?
Antwort1
Kurze Antwort
Das Popup "Nicht genügend Arbeitsspeicher" zeigt an, dass Sie das Limit fürprivat engagiertSpeicher – eine Art virtueller Speicher. Nicht, dass Ihnen der RAM (physischer Speicher) ausgeht. Es spielt keine Rolle, wie vielverfügbarRAM, den Sie haben. Wenn Sie viel verfügbaren RAM haben, können Sie das Commit-Limit nicht überschreiten. Das Commit-Limit ist die Summe Ihrer gesamtRAM (ob verwendet oder nicht!) plus Ihre aktuelle Auslagerungsdateigröße.
Umgekehrt verbraucht das, was das Commit-Limit „verbraucht“ (was meistens die Erstellung von prozessprivatem virtuellem Adressraum ist), nicht unbedingt RAM! Aber das Betriebssystem lässt dessen Erstellung nicht zu, es sei denn, es weiß, dass es einen Platz gibt, um es zu speichern, falls es jemals benötigt wird. Sie können also das Commit-Limit erreichen, ohne Ihren gesamten RAM oder sogar den größten Teil davon zu verwenden.
Aus diesem Grund sollten Sie nicht ohne Auslagerungsdatei arbeiten. Beachten Sie, dass die Auslagerungsdatei möglicherweise nie beschrieben wird! Sie können jedoch die Fehler „wenig Arbeitsspeicher“ und „nicht genügend Arbeitsspeicher“ vermeiden.
Zwischenantwort
Windows gibt eigentlich keine Fehlermeldung aus, wenn der Arbeitsspeicher knapp wird. Was Ihnen ausgeht, ist das „Commit-Limit“.
Das „System“-Diagramm in dieser Version von Process Explorer ist schlecht benannt. Es sollte „Commit Charge“ heißen. (In der Version, die ich habe, heißt es „System Commit“. Besser, aber immer noch nicht ganz einheitlich.) In jedem Fall ist die „aktuelle“ Höhe des Diagramms das, was weiter unten im Textabschnitt als „Commit Charge“ – „Aktuell“ angezeigt wird, und die maximale Höhe des Diagramms stellt „Commit Charge“ – „Limit“ dar.
„Commit Charge“ bezieht sich auf den virtuellen Adressraum, der von der Auslagerungsdatei (falls vorhanden) unterstützt wird. Mit anderen Worten: Wenn nicht alles in den RAM passt, wandert der Rest in die Auslagerungsdatei. (Es gibt andere VAS-Typen, die entweder von anderen Dateien unterstützt werden – das nennt man „mapped“ VAS – oder die ständig im RAM bleiben müssen; letzteres nennt man „nonpageable“.) Das „Commit-Limit“ ist das Maximum, das die „Commit Charge“ betragen kann. Es entspricht Ihrer RAM-Größe plus der Größe der Auslagerungsdatei.
Sie haben anscheinend keine Auslagerungsdatei (das erkenne ich daran, dass Ihr Commit-Limit der Größe Ihres RAM entspricht), daher ist das Commit-Limit einfach die Größe des RAM.
Offenbar haben verschiedene Programme und das Betriebssystem fast das gesamte maximal mögliche Commit genutzt.
Dies hat nichts direkt damit zu tun, wie viel RAM frei oder verfügbar ist. Ja, Sie haben etwa 4,5 GB RAM zur Verfügung. Das bedeutet nicht, dass Sie das Commit-Limit überschreiten können. Commited-Speicher verwendet nicht unbedingt RAM und ist nicht durch die Menge des verfügbaren RAM begrenzt.
Sie müssen entweder die Auslagerungsdatei erneut aktivieren – bei so viel Speicherplatz würde ich eine Auslagerungsdatei mit 16 GB vorschlagen, da Sie das Betriebssystem nicht zwingen möchten, so viel davon im RAM zu behalten, und die Auslagerungsdatei am besten funktioniert, wenn sie viel freien Speicherplatz hat – oder Sie müssen mehr RAM hinzufügen. VIEL mehr. Für eine gute Leistung müssen Sie im RAM viel Platz für Code und andere Dinge haben, die nicht von der Auslagerungsdatei unterstützt werden (aber in andere Dateien ausgelagert werden können).
Sehr lange Antwort
(aber immer noch viel kürzer als das Kapitel zur Speicherverwaltung vonWindows-Interna...)
Angenommen, ein Programm reserviert 100 MB prozessprivaten virtuellen Speicher. Dies geschieht mit einem VirtualAlloc-Aufruf mit der Option „Commit“. Dies führt zu einer Erhöhung der „Commit-Gebühr“ um 100 MB. Aber diese „Zuweisung“ verbraucht tatsächlich keinen RAM! RAM wird nur verwendet, wenn ein Teil des neu reserviertenvirtueller Adressraumzum ersten Mal aufgerufen wird.
Wie der RAM letztendlich genutzt wird
(falls das jemals passiert)
Der erste Zugriff auf den neu zugewiesenen Speicherplatz wäre fast immer ein Schreibvorgang (das Lesen neu zugewiesener privater Vas vor dem Schreiben ist fast immer ein Programmierfehler, da der ursprüngliche Inhalt streng genommen undefiniert ist). Aber ob beim Lesen oder Schreiben, das Ergebnis ist beim ersten Berühren einer Seite neu zugewiesener Vas einSeitenfehler. Obwohl das Wort „Fehler“ schlimm klingt, sind Seitenfehler in einem Betriebssystem mit virtuellem Speicher ein völlig erwartetes und sogar erforderliches Ereignis.
Als Reaktion auf diesen bestimmten Seitenfehlertyp führt der Pager (Teil des Speichermanagers des Betriebssystems, den ich manchmal mit „Mm“ abkürze) Folgendes aus:
- eine physische RAM-Seite zuordnen (idealerweise aus der Nullseitenliste, in jedem Fall aber aus dem, was Windows als „verfügbar“ bezeichnet: die Nullseiten-, freie Seiten- oder Standbyseitenliste, in dieser Reihenfolge);
- füllen Sie einSeitentabelleneintragdie physische Seite mit der virtuellen Seite zu verknüpfen; und schließlich
- Schließen Sie die Seitenfehlerausnahme.
Danach führt der Code, der den Speicherverweis ausgeführt hat, die Anweisung, die den Seitenfehler verursacht hat, erneut aus, und dieses Mal ist der Verweis erfolgreich.
Wir sagen, dass die Seite in den Arbeitsspeicher des Prozesses und in den RAM „eingeschleust“ wurde. Im Task-Manager wird dies als eine Erhöhung des „privaten Arbeitsspeichers“ des Prozesses um eine Seite (4 KB) angezeigt. Und als eine Verringerung des verfügbaren physischen Speichers um eine Seite. (Letzteres kann auf einem ausgelasteten Computer schwer zu erkennen sein.)
Anmerkung 1:Dieser Seitenfehler betraf nichts, was von der Festplatte gelesen wurde. Eine noch nie zuvor aufgerufene Seite des zugesicherten virtuellen Speichers wird nicht auf der Festplatte gespeichert; sie hat keinen Platz auf der Festplatte, um sie zu lesen.aus. Es wird einfach in einer zuvor verfügbaren RAM-Seite „materialisiert“. Statistisch gesehen werden die meisten Seitenfehler tatsächlich im RAM behoben, entweder in gemeinsam genutzten Seiten, die sich bereits für andere Prozesse im RAM befinden, oder in den Seitencaches – den Standby- oder geänderten Listen oder als „Anforderung Null“-Seiten wie diese.
Anmerkung 2:Dies nimmt nur eine Seite (4096 Bytes) von „Verfügbar“ in Anspruch. Nie zuvor berührter, festgeschriebener Adressraum wird normalerweise nur eine Seite auf einmal realisiert – fehlerhaft –, wenn jede Seite zum ersten Mal „berührt“ wird. Es würde keine Verbesserung, keinen Vorteil bringen, wenn man mehr auf einmal macht; es würde nur n-mal so lange dauern. Wenn dagegen Seiten von der Festplatte gelesen werden müssen, wird ein gewisser Teil des „Readahead“-Vorgangs versucht, da die überwiegende Mehrheit der Zeit bei einem Festplattenlesevorgang auf den Overhead pro Vorgang entfällt, nicht auf die eigentliche Datenübertragung. Die „festgeschriebene“ Menge bleibt bei 100 MB; die Tatsache, dass eine oder mehrere Seiten fehlerhaft waren, verringert die Festschreibungsgebühr nicht.
Notiz 3:Nehmen wir an, wir haben 4 GB „verfügbaren“ RAM. Das bedeutet, dass wir bereits zugewiesenen, aber noch nie zuvor referenzierten, festgeschriebenen Speicher etwa eine Million Mal mehr referenzieren könnten (4 GB / 4096), bevor uns der RAM ausgeht. Wenn wir dann eine Auslagerungsdatei haben, wie von David Cutler und Lou Perazzoli vorgesehen, würden einige der am längsten referenzierten Seiten im RAM auf der Festplatte gespeichert und dann zur Verfügung gestellt, um diese neueren Seitenfehler zu beheben. (Tatsächlich würde das Betriebssystem schon vorher RAM-Rückgewinnungsmethoden wie „Working Set Trimming“ einleiten, und die tatsächlichen Schreibvorgänge in die Auslagerungsdatei werden aus Effizienzgründen zwischengespeichert und in der geänderten Seitenliste gebündelt, und und …) Nichts davon würde die „festgeschriebene“ Anzahl beeinflussen. Es ist jedoch für das „Festschreibungslimit“ relevant. Wenn im RAM nicht genug Platz für den gesamten „festgeschriebenen“ Speicher vorhanden ist, kann der Überschuss in der Auslagerungsdatei gespeichert werden. Somit trägt die Größe der Auslagerungsdatei zum „Festschreibungslimit“ bei.
Und es passiert immer wieder ...
Aber nehmen wir an, wir haben diese Millionen weiterer Referenzen nicht durchgeführt und es sind immer noch Seiten im Wert von etwa 4 GB „verfügbar“. Nehmen wir nun an, derselbe Prozess – oder ein anderer, egal – führt eine weitere VirtualAlloc durch, diesmal mit sagen wir 200 MB festgeschrieben. Auch diese 200 MB werden zur Festschreibungsgebühr hinzugefügt und es wird kein verfügbarer RAM entfernt. Durch einfaches VirtualAllocieren des Adressraums wird keine entsprechende Menge RAM verbraucht, und ein geringer „verfügbarer“ RAM begrenzt nicht die Menge des Adressraums, den Sie virtualisieren können (und ein hoher verfügbarer RAM erhöht ihn auch nicht).
(Okay, es gibt einen ganz kleinen Overhead, der sich auf eine (auslagerbare!) Seite beläuft, die für eine Seitentabelle für jeweils 2 MB (4 MB, wenn Sie ein x86-System ohne PAE verwenden) des zugewiesenen virtuellen Adressraums verwendet wird, 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“ zu verbrauchen und gleichzeitig nur eine kleine Menge RAM zu verwenden.
Wenn also das „Commit“ des virtuellen Adressraums keinen RAM verbraucht, warum muss es dann eine Begrenzung geben?
Denn die „Commit Charge“ stellt eine potenzielleZukunftNutzung des Speicherplatzes. „Commit-Limit“ stellt die Gesamtmenge an Speicher (RAM + Auslagerungsdatei-Speicherplatz) dar, die für solche Zuweisungen zur Verfügung steht,falls sie tatsächlich jemals referenziert werden und daher irgendwo gespeichert werden müssen.
Wenn der Mm eine VirtualAlloc-Anforderung genehmigt, verspricht er – „gibt eine Verpflichtung ein“ –, 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 ausreichend Speicher vorhanden ist, um den Inhalt aller dieser Seiten zu speichern, sei es im RAM oder in der Auslagerungsdatei. Der Mm weiß dies, weil er weiß, wie viel Speicherplatz vorhanden ist (das Commit-Limit) und wie viel bereits „commited“ wurde (die aktuelle Commit-Gebühr).
(Auf alle diese Seiten wurde jedoch noch nicht unbedingt zugegriffen, sodass nicht unbedingt der tatsächliche Speicherplatz vorhanden ist, der zu einem bestimmten Zeitpunkt der zugewiesenen Menge entspricht.)
Also... was ist mit „Das System hat nicht genügend Arbeitsspeicher“?
Wenn Sie VirtualAlloc versuchen und die aktuelle Commit-Gebühr plus die angeforderte Zuordnungsgröße Sie über das Commit-Limit bringen würden, UND das Betriebssystem die Auslagerungsdatei nicht erweitern kann, um das Commit-Limit zu erhöhen, wird das Popup „Nicht genügend Arbeitsspeicher“ angezeigt und der Prozess sieht, dass der VirtualAlloc-Aufruf fehlgeschlagen ist. Die meisten Programme geben an diesem Punkt einfach auf und sterben. Einige machen blind weiter, in der Annahme, dass der Aufruf erfolgreich war, und scheitern später, wenn sie versuchen, auf die Region zu verweisen, die sie ihrer Meinung nach zugewiesen haben.
Nochmals (sorry für die Wiederholung): Es spielt keine Rolle, wie viel RAM verfügbar ist. Das Betriebssystem hat versprochen, dass der RAM oder der AuslagerungsspeicherWilleverfügbar sein, wenn es benötigt wird, aber dieses Versprechen mindert nicht die "Verfügbarkeit". Verfügbarer RAM wird nur dann von einer zugesicherten VM verwendet, wenn siereferenziertzum ersten Mal, was dazu führt, dass es „fehlerhaft“ ist … d. h. im physischen Speicher realisiert wird. Und das bloße Festschreiben (= Zuweisen) von virtuellem Speicher tut das nicht. Es nimmt nur freien virtuellen Adressraum und macht daraus nutzbaren virtuellen Adressraum.
Aber im Fall von "Nicht genügend Arbeitsspeicher" gab es eine Zuweisungsanforderung für festgeschriebenen Speicher, und das Betriebssystem hat die aktuelle Festschreibungsgebühr zur Größe dieser neuen Anforderung addiert ... und festgestellt, dass die Gesamtsummemehrals das Commit-Limit. Wenn das Betriebssystem also dieses neue genehmigt,UndDa auf den gesamten Speicherplatz danach verwiesen wurde, gibt es keinen realen Speicherplatz (RAM + Auslagerungsdatei), um alles zu speichern.
Das Betriebssystem lässt dies nicht zu. Es lässt nicht zu, dass mehr VAS zugewiesen werden, als es im schlimmsten Fall an Speicherplatz zur Verfügung hat – selbst wenn alles „ausfällt“. Das ist der Zweck des „Commit-Limits“.
Ich sage es dir dreimal, ich sage es dir dreimal, ich sage es dir dreimal:Die Menge des „verfügbaren“ RAM spielt keine Rolle. Dass der zugewiesene virtuelle Speicherplatz noch nicht den gesamten Speicherplatz nutzt, spielt keine Rolle. Windows kann die virtuelle Zuweisung nicht „festlegen“, es sei denn, es ''kann'' in Zukunft alles fehlerhaft sein.
Beachten Sie, dass es einen anderen Vas-Typ namens „Mapped“ gibt, der hauptsächlich für Code und den Zugriff auf große Datendateien verwendet wird, für den jedoch keine „Commit-Gebühr“ erhoben wird und der nicht durch das „Commit-Limit“ begrenzt ist. Dies liegt daran, dass es über einen eigenen Speicherbereich verfügt, die Dateien, die ihm „zugeordnet“ sind. Die einzige Beschränkung für „Mapped“ Vas ist die Menge an Speicherplatz, die Sie für die zugeordneten Dateien haben, und die Menge an freiem Vas in Ihrem Prozess, in das sie zugeordnet werden können.
Aber wenn ich mir das System anschaue, bin ich noch nicht ganz am Commit-Limit?
Das ist im Grunde ein Mess- und Aufzeichnungsproblem. Sie betrachten das System, nachdem bereits ein VirtualAlloc-Aufruf versucht wurde und fehlgeschlagen ist.
Angenommen, Sie haben nur noch 500 MB Commit-Limit übrig und ein Programm hat versucht, 600 MB per VirtualAlloc zuzuweisen. Der Versuch schlägt fehl. Dann sehen 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 betreffende Prozess zu diesem Zeitpunkt wahrscheinlich vollständig beendet ist und der gesamte zuvor zugewiesene Commit-Speicher freigegeben wurde.
Das Problem ist, dass man nicht in die Vergangenheit zurückblicken und sehen kann, wie hoch die Commit-Gebühr ist.Warin dem Moment, als der Alloc-Versuch unternommen wurde. Und Sie wissen auch nicht, für wie viel Speicherplatz der Versuch war. Sie können also nicht definitiv sehen, warum der Versuch fehlgeschlagen ist oder wie viel mehr „Commit-Limit“ erforderlich gewesen wäre, damit es funktioniert.
Ich habe gesehen "System istlangsam laufenauf dem Gedächtnis". Was ist das?
Wenn im obigen Fall das Betriebssystem die Auslagerungsdatei erweitern KANN (d. h. Sie belassen sie auf der Standardeinstellung „vom System verwaltet“ oder Sie verwalten sie, setzen aber das Maximum größer als das Anfangsniveau UND es ist genügend freier Speicherplatz vorhanden) und eine solche Erweiterung das Commit-Limit ausreichend erhöht, damit der VirtualAlloc-Aufruf erfolgreich ist, dann ... erweitert das Mm die Auslagerungsdatei und der VirtualAlloc-Aufruf ist erfolgreich.
Und dann sehen Sie „Der Speicher des Systems ist zu WENIG“. Das ist eine frühe Warnung, dass Sie, wenn die Dinge ohne Gegenmaßnahmen weitergehen, wahrscheinlich bald eine Warnung „Nicht genügend Speicher“ sehen werden. Es ist Zeit, einige Apps zu schließen. Ich würde mit Ihren Browserfenstern beginnen.
Und Sie meinen, das sei eine gute Sache? Die Auslagerungsdatei-Erweiterung ist böse!!!
Nein, ist es nicht. Sehen Sie, das Betriebssystem „erweitert“ die vorhandene Datei nicht wirklich. Es weist nur einen neuen Bereich zu. Die Wirkung ist ähnlich wie bei jeder anderen nicht zusammenhängenden Datei. Der Inhalt der alten Auslagerungsdatei bleibt genau dort, wo er ist; er muss nicht an einen neuen Ort oder ähnliches kopiert werden. Da die meisten E/A-Vorgänge für Auslagerungsdateien im Vergleich zur Größe der Auslagerungsdatei in relativ kleinen Blöcken erfolgen, ist die Wahrscheinlichkeit, dass eine beliebige Übertragung eine Bereichsgrenze überschreitet, wirklich ziemlich gering, sodass die Fragmentierung nicht viel schadet, es sei denn, sie ist wirklich übermäßig.
Wenn schließlich alle Prozesse beendet wurden, die Speicherplatz in der Erweiterung „festgelegt“ haben (wenn nicht früher, dann beim Herunterfahren des Betriebssystems), werden die Bereiche stillschweigend freigegeben und die Auslagerungsdatei hat wieder ihre vorherige Größe und Zuordnung – wenn sie vorher zusammenhängend war, ist sie es jetzt wieder.
Das Erlauben der Erweiterung der Auslagerungsdatei fungiert daher als völlig kostenloses Sicherheitsnetz: Wenn Sie es zulassen, das System es aber nie benötigt, wird das System die Auslagerungsdatei nicht „ständig erweitern und verkleinern“, wie oft behauptet wird, und es kostetNichtsUnd falls Sie es jemals brauchen, bewahrt es Sie vor App-Abstürzen mit der Fehlermeldung „Kein virtueller Speicher mehr vorhanden“.
Aber, aber, aber...
Ich habe auf Dutzenden von Websites gelesen, dass Windows, wenn Sie die Erweiterung der Auslagerungsdatei zulassen, die Auslagerungsdatei ständig erweitert und verkleinert, und dass dies zu einer Fragmentierung der Auslagerungsdatei führt, bis Sie sie defragmentieren.
Sie liegen einfach falsch.
Wenn das Popup „Wenig Arbeitsspeicher“ (oder in älteren Versionen „Wenig virtueller Arbeitsspeicher“) nie angezeigt wurde, hat das Betriebssystem Ihre Auslagerungsdatei nie erweitert.
Wenn Sie dieses Popup sehen, bedeutet dies, dass Ihre anfängliche Auslagerungsdateigröße zu klein ist. (Ich stelle sie gerne auf etwa das Vierfache der maximal beobachteten Nutzung ein; d. h. der Leistungsindikator „%pagefile usage peak“ sollte unter 25 % liegen. Grund: Der Auslagerungsdateispeicherplatz wird wie jeder andere Heap verwaltet und funktioniert am besten mit viel freiem Speicherplatz.)
Aber warum tun sie es nicht einfach...
Man könnte argumentieren, dass das Betriebssystem die Zuweisung einfach zulassen und dann dieVerweisefehlschlagen, wenn kein RAM zur Behebung der Seitenfehler verfügbar ist. Mit anderen Worten, weiter oben, wo wir beschrieben haben, wie der anfängliche Seitenfehler funktioniert, was wäre, wenn die "Zuweisung einer verfügbaren physischen RAM-Seite" (Schritt 1) nicht durchgeführt werden konnte, weil keine verfügbar war,Undes war kein Platz mehr frei, um etwas auszulagern und verfügbar zu machen?
Dann könnte der Pager den Seitenfehler nicht beheben. Er müsste zulassen, dass die Ausnahme (der Seitenfehler) an den fehlerhaften Thread zurückgemeldet wird, wahrscheinlich geändert in einen anderen Ausnahmecode.
Die Designphilosophie besteht darin, dass VirtualAlloc null (technisch gesehen einen NULL-Zeiger) statt einer Adresse zurückgibt, wenn Sie das Commit-Limit erreichen, und es ist völlig vernünftig, vom Programmierer zu erwarten, dass er weiß, dass ein VirtualAlloc-Aufruf fehlschlagen kann. Von Programmierern wird also erwartet, dass sie diesen Fall prüfen und etwas Vernünftiges als Reaktion darauf tun (z. B. Ihnen die Möglichkeit geben, Ihre Arbeit bis zu diesem Punkt zu speichern und das Programm dann „anständig“ zu beenden). (Programmierer: Sie prüfen doch, ob von malloc, new usw. ein NULL-Zeiger zurückgegeben wird, oder? Warum sollten Sie das dann nicht tun?)
Programmierer sollten jedoch nicht erwarten müssen, dass eine einfache Speicherreferenz wie
i = 0; // initialize loop counter
könnte fehlschlagen - nicht, wenn es sich in einem Bereich mit erfolgreich festgeschriebenem Adressraum befindet. (Oder, was das betrifft, mit zugeordnetem Adressraum.) Aber genau das könnte passieren, wenn die Philosophie „Zuweisung überschrieben zulassen, Speicherreferenz fehlschlagen lassen“ befolgt würde.
Leider gibt es für eine Speicherreferenz wie die in der obigen Codezeile keine praktische Möglichkeit, einen fehlerhaften Status zurückzugeben! Sie sollen nurarbeiten, genau wie Addition und Subtraktion. Die einzige Möglichkeit, solche Fehler zu melden, wären Ausnahmen. Um sie zu behandeln, müsste der Programmierer das gesamte Programm in einen Ausnahmehandler einbinden. (try ... catch und so weiter.)
Das kann man machen... Aber es wäre für den Handler schwierig zu wissen, wie er als Reaktion auf diese Ausnahmen „das Richtige tun“ soll, da es so viele, viele Punkte im Code gäbe, an denen sie auftreten könnten. (Insbesondere könnten sie auftreten beijedenSpeicherverweis auf VirtualAlloc-Speicher, auf mit malloc oder new zugewiesenen Speicher ... und auch auf alle lokalen Variablen, da auch der Stapel VirtualAlloc-Speicher ist.)
Kurz gesagt, es wäre in diesen Fällen sehr schwierig, ein ordnungsgemäßes Abstürzen des Programms zu erreichen.
Andererseits ist es ziemlich einfach, nach einem NULL-Zeiger zu suchen, der von VirtualAlloc (oder malloc oder new, obwohl das nicht genau dasselbe ist) zurückgegeben wird, und dann etwas Vernünftiges zu tun ... beispielsweise nicht zu versuchen, weiterzumachen und das zu tun, wofür das Programm den virtuellen Speicherplatz benötigt hat. Und vielleicht den Benutzer zu fragen, ob er seine bisherige Arbeit speichern möchte, falls überhaupt. (Zugegeben, viel zu viele Apps machen sich nicht einmal die Mühe, das zu tun.)
Andere Benutzer von commit
Übrigens wird das „Commit-Limit“ nicht durch die verschiedenen Zuweisungen des Betriebssystems wie den ausgelagerten und nicht ausgelagerten Pool, die PFN-Liste usw. reduziert; diese werden nur mit der Commit-Gebühr belastet, wenn sie anfallen. Ebenso wenig werden die Commit-Gebühr oder das Commit-Limit durch den Video-RAM oder sogar die „Fenster“-Größe des Video-RAM beeinflusst.
Testen Sie es selbst
Sie können all dies mit dem Testlimit-Tool von der SysInternals-Site vorführen. Die Option -m weist den festgeschriebenen Adressraum zu, „berührt“ ihn aber nicht, führt also nicht zur Zuweisung von RAM. Die Option -d hingegen weist die Seiten zu und verweist auch darauf, was sowohl zu einer Erhöhung der Festschreibungsgebühr als auch zu einer Verringerung des verfügbaren RAM führt.
Verweise
Windows-Internavon Russinovich, Solomon und Ionescu. Es gibt sogar Demonstrationen, mit denen Sie alle diese Punkte mit dem Testlimit-Tool beweisen können. Ich muss Sie jedoch warnen, wenn Sie denken, dies sei lang: Allein das Mm-Kapitel umfasst 200 Seiten; das Obige ist eine EXTREM vereinfachte Version. (Bitte werfen Sie auch einen Blick auf den Abschnitt „Danksagungen“ in der Einleitung.)
Siehe auchMSDN VirtualAlloc-Dokumentation
Antwort2
Vielleicht noch ergänzenddie brillante akzeptierte Antwort:
Windows und die meisten Programme gehen davon aus, dass sie so viel (virtuellen) Speicher wie nötig reservieren können. Dies ist einer der Hauptgründe, warum man die Auslagerungsdatei nicht deaktivieren sollte, siehe vorgeschlagenTatsache 2.2Inmeine Superuser-Frage.
Ich verlinke auch aufdiese brillante Serverfehler-Antwortdort wird deutlich, wie die Auslagerungsdatei funktioniert:
Viele Leute gehen anscheinend davon aus, dass Windows Daten bei Bedarf in die Auslagerungsdatei schiebt. Beispiel: Etwas benötigt viel Speicher und es ist nicht genügend RAM vorhanden, um den Bedarf zu decken. Daher beginnt Windows in letzter Minute wie verrückt, Daten vom RAM auf die Festplatte zu schreiben, damit RAM für den neuen Bedarf freigegeben werden kann.
Das ist falsch. Es passiert mehr unter der Haube. Generell unterhält Windows eineSicherungsspeicher, was bedeutet, dass es alles, was im Speicher ist, auch irgendwo auf der Festplatte sehen möchte. Wenn nun etwas passiert, das viel Speicher benötigt, kann Windows den RAM sehr schnell leeren, da diese Datenbereitsauf der Festplatte, bereit, bei Bedarf wieder in den RAM ausgelagert zu werden. Man kann also sagen, dass ein Großteil der Auslagerungsdatei auch im RAM ist; die Daten wurdenpräventivin der Auslagerungsdatei platziert, um neue Speicherzuweisungsanforderungen zu beschleunigen.
Weiterführende Literaturwird gestelltHier