Was bedeutet Windows' „Speicherauslastung“ eigentlich? — Working Set, Private Bytes, Commit und die Auslagerungsdatei richtig lesen

· · Windows, Windows-Entwicklung, Speicherverwaltung, Working Set, Private Bytes, Commit, Auslagerungsdatei, Leistungsüberwachung, Fehlersuche, Sysinternals

Im Task-Manager zeigt der „Speicher“ eines Prozesses 1,2GB an. Process Explorer zeigt jedoch ein Working Set von 1,5GB und Private Bytes von 2,4GB, und VMMap weist unter „Size“ einen noch größeren Wert aus. Betrachtet man das gesamte System, steht dort „Committed 19,6/31,8GB“.

Wie viele Gigabyte Speicher verbraucht diese Anwendung nun also tatsächlich?

Die Antwort lautet: Welche Zahl relevant ist, hängt davon ab, was Sie eigentlich wissen wollen. Ob Sie die derzeit im RAM liegende Menge wissen möchten, die diesem Prozess spezifisch zugewiesene Menge, die Menge, die das System auch künftig zu stützen verspricht, oder schlicht den Bereich der reservierten virtuellen Adressen — je nachdem ist ein anderer Indikator maßgeblich.

Was Windows-Speicherkennzahlen schwer verständlich macht, ist, dass sie alle unter demselben Wort „Speicher“ angezeigt werden, obwohl sie tatsächlich die folgenden getrennten Achsen messen.

  • Wie viel Adressraum genutzt wird
  • Wie viel Commit verbraucht wurde
  • Ob etwas derzeit im physischen RAM resident ist
  • Ob die Seite prozessspezifisch oder gemeinsam nutzbar ist
  • Wie viel Zuweisung das System insgesamt noch stützen kann

Dieser Artikel richtet sich an alle, die unter Windows 10/11 und aktuellem Windows Server wachsenden App-Speicherverbrauch oder systemweite Speicherengpässe untersuchen, und verbindet die Beziehungen zwischen Working Set, Private Working Set, Private Bytes, Commit, Virtual Bytes, der Auslagerungsdatei, Available und Page Faults zu einem Gesamtbild.

Das Vorgehen zur Ursachensuche, warum .NET-Objekte nicht eingesammelt werden, wird ausführlich in „GC-Wartezeit von einem Speicherleck in .NET unterscheiden“ behandelt, die konkrete Bedienung von VMMap und Process Explorer in „Process Explorer / Handle / VMMap in der Praxis“. Dieser Artikel konzentriert sich auf die dafür nötige Voraussetzung: das Lesen der Zahlen auf Seiten des Windows-Betriebssystems.

1. Das Wichtigste zuerst

  • Working Set sind die Seiten, die derzeit im RAM resident sind. Dazu zählen nicht nur prozessspezifische Seiten, sondern auch mit anderen Prozessen teilbare Seiten wie DLL-Code oder speicherabgebildete Dateien.1
  • Private Working Set ist der Teil des Working Set, der derzeit ausschließlich diesem Prozess gehört. Es eignet sich als Näherung für „das RAM, das dieser Prozess gerade allein belegt“, ist aber nicht die gesamte von der App zugewiesene Menge.2
  • Private Bytes ist die diesem Prozess eigene Commit-Menge. Das ist ein von der aktuellen RAM-Residenz unabhängiger Indikator. Auch das Feld PagefileUsage in der Win32-API-Struktur stellt unter heutigem Windows praktisch dieselbe Commit Charge dar und ist nicht die Anzahl der tatsächlich in die Auslagerungsdatei geschriebenen Bytes.2
  • „Committed X/Y“ im Task-Manager zeigt bei X die aktuelle systemweite Commit-Menge und bei Y die Commit-Obergrenze. X ist nicht die Nutzung der Auslagerungsdatei. Y ergibt sich grob aus RAM plus Auslagerungsdatei.3
  • Reserve und Commit sind unterschiedliche Dinge. Wird ein virtueller Adressbereich nur reserviert (Reserve), wird er lediglich für eine künftige Nutzung vorgemerkt und verbraucht weder RAM noch Commit-Obergrenze in gleicher Höhe.45
  • Ein Page Fault bedeutet nicht zwangsläufig Datenträger-I/O. Es gibt Soft Faults, die sich innerhalb des RAM auflösen lassen, und Hard Faults, die aus der Auslagerungsdatei, ausführbaren Dateien, speicherabgebildeten Dateien und Ähnlichem lesen.16
  • Ein Speicherleck wird nicht anhand eines einzelnen Werts beurteilt, sondern anhand des Trends bei wiederholter gleicher Last. Prüfen Sie insbesondere, ob Private Bytes und dessen Aufschlüsselung nach Abschluss der Verarbeitung schrittweise weiter ansteigen, ohne in denselben stationären Zustand zurückzukehren.

In einem Satz zusammengefasst: Working Set ist „die Menge, die gerade im RAM liegt“, Private Bytes ist „die diesem Prozess speziell versprochene Menge“, und Commit ist „die vom gesamten System versprochene Menge“.

Die richtige Windows-Speicherkennzahl wählenWelche Kennzahl relevant ist, hängt davon ab, ob RAM-Residenz, prozessspezifisches Commit, systemweites Commit oder virtueller Adressbereich von Interesse istMenge, die gerade im RAM liegtprozessspezifisch versprochene Mengesystemweit versprochene Mengereservierter AdressbereichWas möchten Sie über die Speichernutzung wissenWorking SetPrivate BytesSystem CommitVirtual Bytes / ReservedResidenz im physischen RAMProzessspezifisches CommitVergleich mit Commit LimitVirtueller Adressraum

Abbildung 1: Die Beobachtung „der Speicher ist hoch“ zunächst in vier getrennte Fragen zerlegen.

2. „Speichernutzung“ in vier Achsen aufteilen

Betrachten Sie Windows-Speicher zunächst nicht als „einen einzigen Balken“, sondern entlang von vier Achsen.

Vier unabhängige Achsen zur Einordnung einer einzelnen SeiteAdresszustand, Absicherung committeter Seiten, Residenz im physischen RAM und Teilbarkeit mit anderen Prozessen getrennt betrachtenEine Seite entlang vier Achsen betrachtenAdresszustandFree / Reserved / CommittedAbsicherungPage-file-backed / File-backedRAM-ResidenzResident / Nicht residentTeilbarkeitPrivate / Shareable

Abbildung 2: Auch bei einer einzelnen Seite werden Adresszustand, Absicherung, Residenz und Teilbarkeit jeweils unabhängig bestimmt.

Mapped ist kein Adresszustand neben Free, Reserved und Committed, sondern eine Art von Bereich. Auch Seiten einer Mapped View können Committed sein. Ebenso ist Private kein Absicherungsmedium, sondern eine Klassifizierung der Teilbarkeit. Lesen Sie daher die Absicherung getrennt als Page-file-backed oder File-backed und die Teilbarkeit getrennt als Private oder Shareable.

Kombiniert man diese vier Achsen, ergibt sich folgender Zusammenhang zwischen den wichtigsten Kennzahlen.

Seitenzustand Working Set Private Working Set Private Bytes Virtual-Bytes-Familie
Prozessspezifisch, committet, RAM-resident Enthalten Enthalten Enthalten Enthalten
Prozessspezifisch, committet, nicht RAM-resident Nicht enthalten Nicht enthalten Enthalten Enthalten
Gemeinsame Seite einer DLL oder Mapped File, RAM-resident Enthalten In der Regel nicht enthalten In der Regel nicht enthalten Enthalten
Reserviert, aber nicht committet Nicht enthalten Nicht enthalten Nicht enthalten Kann enthalten sein
Ungenutzter Adressbereich Nicht enthalten Nicht enthalten Nicht enthalten Normalerweise nicht enthalten
Zuordnung von Seitentypen zu den wichtigsten SpeicherkennzahlenZeigt, welche Kennzahlen residente private Seiten, nicht-residente private Seiten, residente gemeinsame Seiten und nur reservierte Bereiche einschließenPrivate, committet, RAM-residentPrivate, committet, nicht RAM-residentGemeinsame Seite, RAM-residentReserviert, nicht committetWorking SetPrivate Working SetPrivate BytesVirtual-Bytes-Familie

Abbildung 3: Working Set und Private Bytes zählen unterschiedliche Mengen von Seiten und stehen daher nicht in einer einfachen Enthaltenseinsbeziehung.

Wichtig ist hier, dass Working Set und Private Bytes nicht in einer einfachen Enthaltenseinsbeziehung stehen.

Private Bytes umfasst Seiten, die prozessspezifisch sind, aber derzeit nicht im RAM resident sind. Working Set dagegen umfasst gemeinsame Seiten — etwa DLL-Code oder gemeinsamen Speicher —, die Private Bytes überhaupt nicht mitzählt. Je nach Prozess und Zeitpunkt kann daher Working Set größer sein als Private Bytes, oder umgekehrt.

Summiert man außerdem einfach die Working Sets mehrerer Prozesse, kann dieselbe physische Seite — etwa einer gemeinsam genutzten DLL — mehrfach gezählt werden. „Die Summe der Working Sets aller Prozesse entspricht dem genutzten RAM“ trifft also nicht zwangsläufig zu.

3. Virtueller Adressraum — Reserve und Commit sind unterschiedliche Dinge

3.1. Eine virtuelle Adresse ist keine physische RAM-Adresse

Jeder Prozess besitzt einen eigenen virtuellen Adressraum. Ein Zeiger, mit dem eine App arbeitet, gibt nicht direkt eine Position im physischen RAM an; Windows bildet über Seitentabellen virtuelle Adressen auf physische Seiten oder auf Daten in einer Datei ab.7

Dadurch kann selbst auf einem PC mit 64GB installiertem RAM der virtuelle Adressraum, den ein bestimmter 32-Bit-Prozess nutzen kann, normalerweise weit kleiner sein. Umgekehrt ist es ebenso normal, dass ein 64-Bit-Prozess einen größeren virtuellen Adressraum besitzt als physisch vorhandenes RAM.

3.2. Reserved bedeutet nur „die Adresse ist vorgemerkt“

MEM_RESERVE bei VirtualAlloc reserviert einen zusammenhängenden virtuellen Adressbereich für eine künftige Nutzung. In diesem Stadium ist den Seiten kein physischer Speicher zugeordnet, und der Bereich lässt sich weder lesen noch beschreiben.45

Reserviert beispielsweise eine Datenbank oder Laufzeitumgebung einen 8GB großen Adressbereich für künftiges Wachstum, verbraucht das allein weder 8GB RAM noch 8GB Private Bytes.

3.3. Committed ist das Versprechen, „bei Bedarf zu stützen“

MEM_COMMIT ist der Vorgang, der eine virtuelle Seite in den Zustand Committed versetzt und Windows verspricht, die nötige Absicherung bereitzustellen. Ob tatsächlich Lesen, Schreiben oder Ausführen erlaubt ist, wird separat über den Seitenschutz bestimmt — PAGE_READONLY, PAGE_READWRITE, PAGE_EXECUTE, PAGE_NOACCESS und Ähnliches —, sodass „Committed“ allein nicht „lesbar und beschreibbar“ bedeutet. Im Moment des Committens wird die Seite auf die Commit Charge des Systems angerechnet, aber die tatsächliche physische Seite wird unter Umständen erst beim ersten Zugriff zugewiesen. Eine erstmals berührte Seite wird nullinitialisiert, durchläuft einen Demand-Zero Fault und gelangt so ins Working Set.51

Auch wenn beides als „reserviert/zugewiesen“ bezeichnet wird, gibt es also folgende drei Stufen.

Drei Stufen von Reserve über Commit bis zur RAM-ResidenzZeigt den Ablauf, bei dem eine virtuelle Adresse reserviert, eine Seite committet und beim ersten Zugriff eine physische Seite zugewiesen wird und ins Working Set gelangtMEM_COMMITErster Zugriff, Demand-Zero FaultFalls nie zugegriffenMEM_RESERVE: Adressbereich reservierenWirkt sich auf die Virtual-Bytes-Familie ausCommittet: zugänglich je nach SeitenschutzWirkt sich auf Private Bytes / System Commit ausPhysische Seite zugewiesen, RAM-residentWirkt sich auf Working Set ausCommittet, aber nicht resident

Abbildung 4: Reserve, Commit und der erste Zugriff sind getrennte Ereignisse, die jeweils eine andere Kennzahl bewegen.

Diese drei Stufen bewegen die Zahlen der Virtual-Bytes-Familie, von Private Bytes und von Working Set jeweils getrennt.

3.4. Warum OutOfMemory auch bei freiem RAM auftreten kann

Ob eine Speicherzuweisung gelingt, hängt nicht allein vom freien RAM ab.

  • Der virtuelle Adressraum des Prozesses ist erschöpft
  • Es gibt keinen zusammenhängenden freien Adressbereich in der benötigten Größe
  • Die systemweite Commit Charge hat das Commit Limit erreicht
  • Ein Job-Objekt, ein Container, eine Laufzeitumgebung oder eine Bibliothek hat eine eigene Obergrenze
  • Es handelt sich um einen 32-Bit-Prozess
  • Der native Heap ist fragmentiert

Auch unter 64-Bit-Windows ist der virtuelle Adressraum eines 32-Bit-Prozesses im Benutzermodus normalerweise auf 2GB begrenzt, wenn IMAGE_FILE_LARGE_ADDRESS_AWARE nicht gesetzt ist. Eine 32-Bit-App mit gesetztem Flag kann unter 64-Bit-Windows bis zu 4GB nutzen.8

„Der PC hat 20GB freien RAM, und trotzdem scheitert die 32-Bit-App bei rund 1,6GB“ ist daher kein Widerspruch. Es muss sich nicht um ein RAM-Problem handeln, sondern kann an Fragmentierung des Adressraums oder an einer erreichten Obergrenze liegen.

4. Working Set — die Seiten, die gerade im RAM liegen

Working Set ist die Menge der Seiten innerhalb des virtuellen Adressraums eines Prozesses, die derzeit im physischen RAM resident sind.1

Darin mischen sich folgende Bestandteile.

  • Der prozesseigene Heap und Stack
  • Code und schreibgeschützte Daten von EXE und DLLs
  • Speicherabgebildete Dateien
  • Gemeinsamer Speicher
  • Seiten, die nach Copy-on-Write prozesseigen wurden
  • Von der Laufzeitumgebung und verschiedenen Bibliotheken berührte Seiten

4.1. Ein wachsendes Working Set bedeutet nicht zwangsläufig eine größere Zuweisung

Wird eine bereits committete Seite erstmals aufgerufen, kann allein das Working Set wachsen, während Private Bytes unverändert bleibt. Wird eine große Datei speicherabgebildet und der Reihe nach gelesen, gelangen ebenso dateibasierte Seiten ins Working Set, während Private Bytes kaum zunimmt.

Trimmt Windows umgekehrt das Working Set aufgrund von Speicherdruck, sinkt allein das Working Set, während die App logisch weiterhin denselben Speicher hält. Wird später erneut darauf zugegriffen, kehrt es über einen Page Fault zurück.

Ein Rückgang des Working Set bedeutet daher nicht zwangsläufig, „die App hat freigegeben“, und ein Anstieg nicht zwangsläufig, „die App hat neu zugewiesen“.

Ein typischer Ablauf, bei dem nur das Working Set steigt und sinktDieselbe committete Seite gelangt beim ersten Zugriff ins RAM, wird durch Trim nicht-resident und kehrt bei erneutem Zugriff zurück, während Private Bytes durchgehend angerechnet bleibtErster ZugriffTrim bei SpeicherdruckPage Fault bei erneutem ZugriffDieselbe committete SeiteRAM-residentNicht residentIm Working Set enthaltenNicht im Working Set enthaltenSolange committet, in Private Bytes angerechnet

Abbildung 5: Working Set steigt und sinkt mit dem Residenzstatus, aber Private Bytes sinkt nicht, solange das Commit derselben Seite bestehen bleibt.

4.2. Working Set enthält auch gemeinsame Seiten

Teilen sich 10 Prozesse dieselben Code-Seiten einer DLL, kann diese Seite im Working Set jedes einzelnen Prozesses erscheinen, obwohl im physischen RAM nur ein einziges Exemplar existiert. Übersteigt die Summe der Working Sets das installierte RAM, ist das nicht sofort ein Anzeichen für ein Problem.

Wer sich „dem RAM, das dieser Prozess gerade allein belegt“ annähern möchte, betrachtet Private Working Set. Aber auch das ist nicht „der gesamte von diesem Prozess zugewiesene Speicher“, sondern ausschließlich die derzeit residenten privaten Seiten.

4.3. Das erzwungene Verkleinern des Working Set behebt kein Leck

Mit EmptyWorkingSet oder SetProcessWorkingSetSize lassen sich Seiten aus dem Working Set eines Prozesses verdrängen. Das ist jedoch kein Vorgang, der Commit freigibt oder Referenzen auf dem Heap löst. Die scheinbare RAM-Nutzung sinkt, während Private Bytes unverändert bleibt, und beim nächsten Zugriff kann eine Welle von Page Faults auftreten.9

Sinkt die Zahl im Task-Manager nur unmittelbar nach dem Drücken einer Schaltfläche „Speicher reduzieren“ und steigt sie sofort wieder, sobald die Arbeit fortgesetzt wird, handelt es sich womöglich nur um ein Trim des Working Set und nicht um eine echte „Freigabe“.

5. Private Bytes — die einem Prozess eigene Commit-Menge

Private Bytes ist die Menge des virtuellen Speichers, der ausschließlich für diesen Prozess committet wurde. Es stellt eine Commit Charge dar, die nicht mit einem anderen Prozess geteilt werden kann, unabhängig davon, ob sie derzeit im RAM resident ist. In Microsofts PROCESS_MEMORY_COUNTERS_EX entspricht PrivateUsage diesem Wert.102

Die Win32-API besitzt außerdem das verwirrend benannte Feld PagefileUsage, das die aktuelle Dokumentation jedoch als „die Commit Charge dieses Prozesses“ definiert und als denselben Wert wie PrivateUsage beschreibt. Mit anderen Worten: Private Bytes von 2GB bedeutet nicht, dass „2GB in pagefile.sys geschrieben wurden“.2

Auf Private Bytes wirken sich typischerweise folgende Punkte aus.

  • Das Commit des nativen Heaps, den HeapAlloc, malloc, new und Ähnliches nutzen
  • Private Data, die direkt mit VirtualAlloc committet wurde
  • Der committete Bereich des .NET-GC-Heaps
  • Der tatsächlich committete Teil eines Thread-Stacks
  • Die Commit Charge für die gesamte View, die beim Mappen einer Copy-on-Write-View (FILE_MAP_COPY) reserviert wird
  • Private Puffer, die Bibliotheken oder Geräte-SDKs intern vorhalten

Bei einer mit FILE_MAP_COPY erzeugten Copy-on-Write-View kann jede einzelne Seite künftig privat werden, weshalb Windows bereits beim Mappen die Commit Charge reserviert, um die gesamte View über die Auslagerungsdatei absichern zu können. Dadurch können System Commit und die Commit Charge des Prozesses (Private Bytes) um den Umfang der gesamten View steigen, noch bevor durch einen tatsächlichen Schreibzugriff eine private Kopie entsteht.11

5.1. Warum Private Bytes auch nach free oder einer GC nicht sinkt

Auch wenn Speicher aus Sicht der Anwendung „freigegeben“ wird, geben Laufzeitumgebung oder Heap-Allokator diesen Bereich mitunter nicht per Decommit an das Betriebssystem zurück, sondern behalten ihn zur späteren Wiederverwendung. In diesem Fall bleibt Private Bytes hoch, obwohl der Bereich intern in der App wiederverwendbar ist.

Auch Gründe wie das Überleben nur eines Teils eines großen Bereichs, Fragmentierung oder ein bis zur Obergrenze aufgewärmter Cache beziehungsweise Pool können zu einem dauerhaft hohen Wert führen.

Ein hoher Wert bei Private Bytes allein beweist daher kein Leck. Zu betrachten ist vielmehr ein Vergleich über die Zeit:

  1. Denselben Vorgang dieselbe Anzahl von Malen wiederholen
  2. Nach der Verarbeitung dieselbe Wartezeit einhalten
  3. Prüfen, ob Private Bytes auf denselben Stand zurückkehrt oder bei einem festen Wert stagniert
  4. Mit VMMap oder einem Heap-Dump prüfen, welcher Bereich oder Typ gewachsen ist
Warum Private Bytes auch nach free oder einer GC nicht sinktPrivate Bytes verändert sich unterschiedlich, je nachdem ob der Allokator einen von der App nicht mehr benötigten Bereich an das Betriebssystem zurückgibt oder zur Wiederverwendung behältDecommit / ReleaseBehält zur WiederverwendungApp gibt einen Bereich per free / GC freiGibt der Allokator ihn an das Betriebssystem zurückCommit Charge sinktPrivate Bytes sinktBereich bleibt committetPrivate Bytes stagniert hochPools, Caches, Fragmentierung

Abbildung 6: Dass ein Bereich innerhalb der App wiederverwendbar wird, ist nicht dasselbe wie die Rückgabe seines Commits an das Betriebssystem.

5.2. Ein starkes Indiz für ein Leck

Ein Anstieg wie der folgende, bei dem sich die Untergrenze mit jeder Lastrunde treppenförmig nach oben verschiebt, verdient besondere Aufmerksamkeit.

Private Bytes
  ^
  |                    ________
  |             ______|
  |      ______|
  |_____|
  +----------------------------> Wiederholungen desselben Vorgangs

Allerdings kann auch eine treppenförmige Kurve nur ein paar Runden Wachstum durch erstmaliges JIT, Schriftarten, Bilddecoder, Verbindungspools oder das Aufwärmen eines Caches darstellen, wonach sie sich stabilisiert. Entscheidend ist nicht dass ein Anstieg vorliegt, sondern dass kein stationärer Zustand erreicht wird.

6. System Commit — was „Committed X/Y“ tatsächlich bedeutet

Der Wert „Committed X/Y“ auf der Registerkarte [Leistung] → [Speicher] des Task-Managers ist eine systemweite Kennzahl.

  • X: System Commit Charge — der committete Speicher, den Windows derzeit systemweit zu stützen verspricht
  • Y: System Commit Limit — die Obergrenze des Commits, die das System stützen kann

Das Commit Limit ergibt sich grob aus dem physischen RAM zuzüglich der Summe aller Auslagerungsdateien. Ohne Auslagerungsdatei fällt es etwas kleiner aus als das installierte RAM.36

Der Zusammenhang zwischen System Commit Charge und Commit LimitProzessspezifisches, gemeinsam genutztes und Kernel-Commit ergeben den aktuellen Wert X, während physisches RAM und Auslagerungsdatei die Obergrenze Y stützenX kann Y nicht überschreitenPrivates Commit jedes ProzessesSystem Commit Charge: XCommit von durch die Auslagerungsdatei abgesicherten gemeinsamen SectionsCommit des KernelsPhysisches RAMSystem Commit Limit: YAuslagerungsdatei

Abbildung 7: X ist die aktuell versprochene Menge, Y die Obergrenze, die dieses Versprechen stützen kann — keine Anzeige der Nutzung der Auslagerungsdatei.

Zur System Commit Charge zählt nicht nur die Summe der Private Bytes aller Prozesse, sondern auch das Commit von über die Auslagerungsdatei abgesicherten gemeinsamen Sections sowie das vom Kernel verbrauchte Commit. Die Summe der prozessweisen Private Bytes allein kann X daher nicht vollständig erklären.

6.1. Commit Charge ist keine Nutzung der Auslagerungsdatei

Betrachten Sie ein System mit 16GB RAM, 16GB Auslagerungsdatei und Committed bei 20/31GB.

Diese 20GB bedeuten nicht, dass „20GB in die Auslagerungsdatei geschrieben wurden“. Die 20GB sind die Gesamtmenge, für die Windows verspricht, bei Bedarf RAM- oder Auslagerungsdatei-Absicherung bereitzustellen — etwa für private, veränderbare Seiten.

Zu diesem Zeitpunkt liegt eine Mischung folgender Zustände vor:

  • Ein Großteil ist im RAM resident
  • Ein Teil ist in die Auslagerungsdatei ausgelagert
  • Manches ist committet, wurde aber noch nie erstmals aufgerufen
  • Manches wird als Commit auf Kernelseite verbraucht

Möchten Sie die tatsächliche Nutzung der Auslagerungsdatei sehen, prüfen Sie getrennt von Commit Paging File(*)\% Usage. Allerdings erklärt auch Microsofts eigenes Material, dass eine hohe Nutzung der Auslagerungsdatei allein nicht zwangsläufig ein Leistungsproblem bedeutet und gemeinsam mit dem Erreichen des Commit Limit, der Modified Page List und der tatsächlichen Paging-I/O beurteilt werden sollte.6

6.2. Was passiert, wenn sich das System dem Commit Limit nähert

Erreicht die System Commit Charge das Commit Limit, können neue Commit-Anforderungen nicht mehr gestützt werden. Das führt zu fehlgeschlagenen Speicherzuweisungen von Prozessen, Absturz von Anwendungen und einem nicht mehr reagierenden System.3

Hier ist die X/Y-Relation des Commits wichtiger als „freies RAM“. Trimmen Sie Working Sets, um RAM freizugeben, löst das das Erreichen des Commit Limit nicht, solange die Commit Charge selbst nicht sinkt.

6.3. Die drei Aufgaben der Auslagerungsdatei

Die Auslagerungsdatei erfüllt hauptsächlich folgende Aufgaben.

  1. Das Commit Limit erweitern
  2. Das Auslagern selten genutzter, veränderter Seiten aus dem RAM ermöglichen
  3. Je nach Konfiguration das Systemabsturzabbild stützen

Das Deaktivieren der Auslagerungsdatei ist kein einfacher Fall von „die Datenträger-I/O sinkt zwangsläufig, und alles wird schneller“. Vielmehr senkt es das Commit Limit, macht es wahrscheinlicher, dass geänderte, aber momentan nicht benötigte Seiten im RAM verbleiben, und kann dazu führen, dass bei einem Absturz nicht das benötigte Abbild erfasst werden kann.36

Die passende Größe der Auslagerungsdatei lässt sich nicht allein aus dem installierten RAM ableiten. Auch Microsoft erklärt, dass sich dies nicht verallgemeinern lässt, da die Spitzen-System-Commit-Charge und die Art des benötigten Absturzabbilds von System zu System unterschiedlich sind.6

7. Die Zusammensetzung des physischen RAM — nicht allein an niedrigem Available urteilen

Physisches RAM wird nicht nur von den Working Sets der Benutzerprozesse verbraucht.

  • Working Set jedes Prozesses
  • Der System-Dateicache
  • Seitenlisten wie Standby, Modified, Free und Zeroed
  • Der Paged Pool / Nonpaged Pool des Kernels
  • Von Gerätetreibern gehaltener Speicher
  • Die Ablage der Speicherkomprimierung
  • Mit GPU oder anderen Geräten gemeinsam genutzte oder für sie reservierte Bereiche
  • Hardware-reservierter Speicher

7.1. Available umfasst auch wiederverwendbaren Cache

Windows’ Available MBytes ist nicht einfach vollständig ungenutztes RAM. Der Indikator umfasst neben Free und Zeroed auch Standby-Seiten, die bei Bedarf wiederverwendet werden können.12

  • Free: Seiten, die derzeit keinem Zweck zugewiesen sind
  • Zeroed: Seiten, die nullinitialisiert wurden, damit sie sicher an einen anderen Prozess übergeben werden können
  • Standby: Seiten, die aus einem Working Set entfernt wurden, deren Inhalt aber weiterhin im RAM zwischengespeichert ist
  • Modified: Seiten, deren Inhalt geändert wurde und die vor der Wiederverwendung in eine geeignete Absicherung zurückgeschrieben werden müssen
Die Bewegung zwischen Working Set und den SeitenlistenZeigt, wie unveränderte Seiten nach Standby und geänderte Seiten nach Modified wechseln, gefolgt von erneutem Zugriff, Rückschreiben und WiederverwendungUnveränderte Seite entfernenGeänderte Seite entfernenRückschreiben abgeschlossenErneuter ZugriffFür anderen Zweck wiederverwendetNullinitialisierungZugriff nach ZuweisungWorking Set: in VerwendungStandby: Wiederverwendungskandidat mit erhaltenem InhaltModified: wartet auf RückschreibenFür anderen Zweck zugewiesenFree: ungenutztZeroed: für Neuzuweisung verfügbarIn Available enthalten

Abbildung 8: Available umfasst nicht nur vollständig freien Speicher, sondern auch Standby, das bei Bedarf wiederverwendet werden kann.

„Um freies RAM zu vergrößern, den gesamten Cache zu verwerfen“ ist nicht immer von Vorteil. Liegen die benötigten Daten noch im Standby, kann ein erneuter Zugriff sie schnell zurück ins Working Set holen, ohne von der Festplatte zu lesen.

Ist daher im Task-Manager Free niedrig, Available aber ausreichend vorhanden, und treten keine Hard Faults oder Datenträgerwartezeiten als Problem auf, nutzt Windows das RAM womöglich lediglich effektiv als Cache.

7.2. Wenn RAM ohne große Prozesse schrumpft

Es ist nicht ungewöhnlich, dass sich der Speicherverbrauch selbst nach Summierung des Private Working Set jedes Prozesses nicht erklären lässt.

  • Dateicache und speicherabgebildete Dateien
  • Nonpaged Pool / Paged Pool
  • Von einem Treiber gesperrte Seiten
  • Gemeinsame Seiten
  • Speicherkomprimierung
  • Mit Virtualisierung oder der GPU zusammenhängende Zuweisungen

In diesem Fall prüfen Sie, statt weiter die Prozessliste zu betrachten, in Sysinternals’ RAMMap die Werte Use Counts, Processes, Priority Summary und File Summary. RAMMap ist das offizielle Werkzeug, um physischen Speicher nach Verwendungszweck, Seitenliste und Datei aufzuschlüsseln.13

Wächst allein der Nonpaged Pool immer weiter, ist das der Punkt, an dem eher ein Leck auf Treiber- oder Kernel-Seite zu vermuten ist als in den Private Bytes einer Anwendung im Benutzermodus.

8. Page Fault — ein hoher Wert allein ist keine Anomalie

Ein Page Fault tritt auf, wenn ein Prozess auf eine Seite zugreift, die sich derzeit nicht in seinem Working Set befindet. Trotz des Wortes „Fault“ im Namen handelt es sich nicht um einen außergewöhnlichen Fehler, sondern um den normalen Mechanismus, der virtuellen Speicher antreibt.1

8.1. Soft Faults

Diese lassen sich ohne Lesen von der Festplatte auflösen.

  • Die Seite befindet sich noch in Standby oder Transition
  • Dieselbe gemeinsame Seite liegt bereits im Working Set eines anderen Prozesses
  • Eine committete Seite wird erstmals aufgerufen, und eine Nullseite wird zugewiesen
  • Das Read-ahead des Speichermanagers hat sie bereits ins RAM geholt

Deshalb bedeutet ein hoher Wert bei \Memory\Page Faults/sec nicht zwangsläufig, dass Datenträger-I/O oder -Latenz auftritt.

8.2. Hard Faults

Diese erfordern das Lesen von Inhalten aus einem Backing Store auf dem Datenträger. Die Quelle ist nicht auf die Auslagerungsdatei beschränkt.

  • Code und Daten einer .exe oder .dll
  • Eine speicherabgebildete Datei
  • Die Auslagerungsdatei
Die Verzweigung zwischen Soft und Hard Page FaultsBeim Zugriff auf eine nicht im Working Set befindliche Seite wird bei nicht erforderlichem Storage-I/O ein Soft Page Fault, bei erforderlichem ein Hard Page Fault behandeltNein: Standby, gemeinsam genutzt, Demand-Zero usw.JaZugriff auf eine Seite außerhalb des Working SetIst Storage-I/O erforderlichSoft Page FaultGelangt ins Working Set, ohne den Datenträger zu lesenHard Page FaultWoher wird gelesenEXE / DLLSpeicherabgebildete DateiAuslagerungsdateiNach dem Laden ins Working Set

Abbildung 9: Der Name „Page Fault“ allein sagt nichts darüber aus, ob Datenträger-I/O stattgefunden hat.

Microsoft nennt \Memory\Pages/sec, \Memory\Page Reads/sec und \Memory\Pages Input/sec als Zähler zur Messung von Hard Faults. Da hohe Werte hierbei nicht zwangsläufig auf wenig Speicher hindeuten, sollten Sie sie mit Available MBytes, Datenträgerlatenz und der tatsächlichen Antwortzeit korrelieren.6

8.3. Keine pauschale Schwelle festlegen

Ein fester Wert wie „ab 1000 Page Faults/sec liegt eine Anomalie vor“ ändert seine Bedeutung je nach Datenträger, Seitengröße, Workload und Zugriffslokalität.

In der Praxis stellen Sie Folgendes auf derselben Zeitachse nebeneinander.

  • Memory\Available MBytes
  • Memory\Pages Input/sec
  • Memory\Page Reads/sec
  • Read-Latenz / Queue des betroffenen Datenträgers
  • Working Set und Private Bytes des betroffenen Prozesses
  • Verarbeitungszeit, Timeouts und UI-Reaktionsfähigkeit der App

Sinkt Available gleichzeitig mit steigender Last, steigen Pages Input/sec und Datenträgerwartezeit, und verschlechtert sich zugleich die Verarbeitungszeit, ist damit die Grundlage gegeben, um durch physischen Speicherdruck verursachtes Paging zu vermuten.

9. Welcher Bildschirm oder welches Werkzeug zeigt was

Was Sie wissen möchten Zuerst zu prüfende Kennzahl Wichtige Werkzeuge
Wie viel der betrachtete Prozess derzeit im RAM hält Working Set Task-Manager, Process Explorer, Get-Process
Davon der prozessspezifische Anteil im RAM Private Working Set / Working Set - Private Detailspalten des Task-Managers, Process Explorer, PerfMon
Die dem betrachteten Prozess eigene Commit-Menge Private Bytes / Commit Size Process Explorer, PerfMon, VMMap, Get-Process
Der virtuelle Adressbereich des Prozesses Virtual Bytes / Size Process Explorer, VMMap, Get-Process
Der systemweite Commit-Spielraum Committed Bytes / Commit Limit Task-Manager [Leistung], PerfMon
Der Wiederverwendungsspielraum des physischen RAM Available MBytes Task-Manager, PerfMon
Die Aufschlüsselung von Standby, Modified und Dateicache Seitenlisten-/Verwendungsaufschlüsselung RAMMap
Was innerhalb von Private Bytes gewachsen ist Heap / Private Data / Managed Heap usw. VMMap, WinDbg, laufzeitspezifische Dumps
Paging mit Datenträgerbeteiligung Pages Input/sec, Page Reads/sec, Datenträgerlatenz PerfMon, WPR/WPA
Ein Werkzeug zur Windows-Speicheruntersuchung wählenDas passende Werkzeug hängt davon ab, ob das Ziel ein einzelner Prozess oder das gesamte System ist, ob ein einzelner Zeitpunkt oder eine Zeitreihe betrachtet wird und ob die Bindung innerhalb einer Laufzeitumgebung nachverfolgt werden mussJaAufschlüsselung zu einem ZeitpunktZeitreiheGesamtes SystemAufschlüsselung des physischen RAMZeitachse einschließlich CPU, I/O und Wartezeiten.NET-HeapNativer HeapWas möchten Sie eingrenzenIst das Ziel ein einzelner ProzessEin einzelner Zeitpunkt oder eine ZeitreiheVMMapPerfMon / PowerShellAufschlüsselung des physischen RAM oder ZeitachseRAMMapWPR / WPAMuss die Bindung innerhalb einer Laufzeitumgebung nachverfolgt werdendotnet-dump / PerfViewWinDbg / Application Verifier

Abbildung 10: Wer zuerst den Umfang und die Zeitachse festlegt, wählt genau das nötige Werkzeug — nicht mehr und nicht weniger.

9.1. Task-Manager

Betrachten Sie im Task-Manager die Bildschirme getrennt.

  • [Prozesse] oder [Details]: die Working-Set-Familie und die Commit-Size-Familie einzelner Prozesse
  • [Leistung] → [Speicher]: systemweite Werte für In Verwendung, Verfügbar, Committed, Cached, Paged Pool, Non-paged Pool

Urteilen Sie nicht allein anhand der Spalte namens „Speicher“ — klicken Sie mit der rechten Maustaste auf die Spaltenüberschriften der Registerkarte [Details] und fügen Sie die benötigten Spalten hinzu, etwa Working Set, Spitzenwert Working Set und Commit Size. Da sich Spaltennamen je nach Windows-Version und Anzeigesprache unterscheiden können, prüfen Sie die tatsächliche Bedeutung einer Spalte, bevor Sie sie protokollieren.

9.2. Eine Zeitreihe mit PowerShell erfassen

Kennen Sie die ID des betreffenden Prozesses, können Sie mit Get-Process den Verlauf von Working Set, Private Bytes und Virtual Bytes gemeinsam erfassen.

param(
    [Parameter(Mandatory)]
    [int]$ProcessId,

    [int]$IntervalSeconds = 5,
    [int]$SampleCount = 60
)

$samples = for ($i = 0; $i -lt $SampleCount; $i++) {
    $process = Get-Process -Id $ProcessId -ErrorAction Stop

    [pscustomobject]@{
        Timestamp      = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
        ProcessId      = $process.Id
        WorkingSetMB   = [math]::Round($process.WorkingSet64 / 1MB, 1)
        PrivateBytesMB = [math]::Round($process.PrivateMemorySize64 / 1MB, 1)
        VirtualBytesMB = [math]::Round($process.VirtualMemorySize64 / 1MB, 1)
        Handles        = $process.HandleCount
        Threads        = $process.Threads.Count
    }

    Start-Sleep -Seconds $IntervalSeconds
}

$samples | Format-Table -AutoSize
$samples | Export-Csv .\memory-samples.csv -NoTypeInformation -Encoding utf8

.NETs Process.WorkingSet64 entspricht Working Set, PrivateMemorySize64 entspricht Private Bytes, und VirtualMemorySize64 entspricht Virtual Bytes.141516

Bei einer App mit mehreren Instanzen verfolgen Sie den Verlauf über die PID statt über den Namen. Bei einer Langzeitüberwachung, bei der ein Neustart die PID ändert, ist ein Aufbau nötig, der Startzeit, Dienstname und Ähnliches protokolliert, damit das Ziel nie verwechselt wird.

9.3. System und Prozess mit PerfMon auf dieselbe Zeitachse bringen

Werden mindestens die folgenden Werte gemeinsam aufgezeichnet, lässt sich leichter eingrenzen.

\Process(<Ziel>)\ID Process
\Process(<Ziel>)\Working Set
\Process(<Ziel>)\Working Set - Private
\Process(<Ziel>)\Private Bytes
\Process(<Ziel>)\Virtual Bytes

\Memory\Available MBytes
\Memory\Committed Bytes
\Memory\Commit Limit
\Memory\Pages Input/sec
\Memory\Page Reads/sec
\Memory\Pool Nonpaged Bytes
\Memory\Pool Paged Bytes

Gibt es mehrere Prozesse mit demselben Namen, oder findet während der Überwachung ein Neustart statt, lässt sich das Ziel allein über den Instanznamen — Process(name) oder Process(name#N) — nicht eindeutig festlegen. Zeichnen Sie bei jeder Probe zusätzlich ID Process auf und übernehmen Sie nur die Instanz, deren Wert mit der verfolgten PID übereinstimmt. Überspannt die Überwachung einen Neustart, der die PID ändert, protokollieren Sie den Zeitpunkt des Wechsels zusätzlich getrennt.

Namen von Windows-Leistungsindikatoren können je nach Anzeigesprache lokalisiert sein. Lässt sich der englische Name in PowerShell nicht direkt angeben, fügen Sie den Zähler über die PerfMon-Oberfläche hinzu, oder prüfen Sie die Namen in Ihrer lokalen Umgebung mit Get-Counter -ListSet *.

9.4. Rollen von VMMap und RAMMap nicht verwechseln

  • VMMap: schlüsselt den virtuellen Speicher und das Working Set eines einzelnen Prozesses nach Heap, Image, Mapped File, Private Data, Managed Heap und Ähnlichem auf
  • RAMMap: schlüsselt das physische RAM des gesamten Systems nach Verwendungszweck, Seitenliste, Prozess und Datei auf

„Wodurch sind die Private Bytes dieses Prozesses gewachsen“ ist eine Aufgabe für VMMap, „wofür wird das RAM verwendet, das sich aus der Prozessliste nicht erklären lässt“ eine Aufgabe für RAMMap.1713

10. Symptome aus Kombinationen von Werten lesen

Beobachtetes Muster Erste Vermutung Was als Nächstes zu prüfen ist
Working Set steigt, Private Bytes bleibt stabil Erster Zugriff auf vorhandene Seiten, gemeinsame DLL, Mapped File, Dateicache Image / Mapped File in VMMap, Pages Input/sec
Private Bytes steigt, Working Set bleibt stabil Privates Commit ist gewachsen, aber nicht resident oder wurde getrimmt Heap / Private Data / Managed Heap in VMMap
Beides steigt direkt nach dem Start und flacht danach ab JIT, Cache, Pool, Aufwärmen bei der Initialisierung Ob es unter derselben zusätzlichen Last erneut steigt
Die Untergrenze von Private Bytes steigt mit jeder Lastrunde Ein Leck, ein unbegrenzter Cache oder ein Allokator, der nach Freigabe Speicher behält VMMap-Schnappschüsse vor und danach, ein Heap-Dump
Nur Working Set fällt plötzlich und kehrt bei Aktivität zurück Betriebssystem oder App hat das Working Set getrimmt Private Bytes, Pages Input/sec, Antwortzeit
X in Committed X/Y nähert sich Y Systemweiter Commit-Druck Größte Verbraucher von Private Bytes, Paged/Nonpaged Pool, Auslagerungsdatei-Einstellungen
Available ist niedrig, Pages Input/sec und Datenträgerlatenz sind hoch Physischer RAM-Druck und Hard Paging Größte Working-Set-Verbraucher, RAMMap, Korrelation mit der Workload
RAM-Nutzung ist hoch, aber es gibt keinen großen Prozess Cache, gemeinsame Seiten, Kernel-Pools, Treiber, Komprimierung usw. RAMMap, Pool Nonpaged/Paged Bytes
Freies RAM ist vorhanden, aber nur die 32-Bit-App scheitert Obergrenze des virtuellen Adressraums oder Fragmentierung Free/Reserved in VMMap, LAA-Einstellung der ausführbaren Datei
Private Bytes ist hoch, wächst aber bei wiederholter Verarbeitung nicht weiter Möglicherweise ein Pool oder Cache, der einen Höchststand hält Seine Obergrenze, Wiederverwendungsverhalten, Stabilität nach dem Höchststand

Das Wichtigste an dieser Tabelle ist, sie in Kombination und nicht anhand eines einzelnen Werts zu lesen.

11. Praktisches Vorgehen bei der Untersuchung eines Speicherlecks

11.1. Zunächst Reproduktionsbedingungen und stationären Punkt festlegen

„Es wächst über mehrere Tage“ allein lässt sich nicht vergleichen.

  • Wie viel vom Aufwärmen nach dem Start einbezogen wird
  • Woraus ein Zyklus der Bedienung besteht
  • Wie viele Sekunden nach einem Zyklus gewartet wird
  • Wie viele Runden bis zur Cache-Obergrenze nötig sind
  • Ob dieselbe Eingabe für die fehlerfreie und die fehlerhafte Version verwendet werden kann

Legen Sie all dies fest.

11.2. Prozess und System gleichzeitig aufzeichnen

Protokollieren Sie mindestens die folgenden Werte zu denselben Zeitpunkten.

  • Working Set des Ziels
  • Private Bytes des Ziels
  • Virtual Bytes des Ziels
  • Committed Bytes / Commit Limit des Systems
  • Available MBytes
  • Pages Input/sec
  • Anzahl der Handles, Anzahl der Threads
  • Anzahl der Vorgänge oder verarbeiteten Elemente

Bleiben die Private Bytes des Prozesses stabil, während allein der Commit des Systems weiter wächst, müssen Sie den Blick auf andere Prozesse, den Kernel, Treiber und gemeinsame Sections erweitern.

11.3. Zuerst festlegen, welche „Dimension“ wächst

  • Nur Working Set: residente Seiten, gemeinsam genutzt oder dateibasiert, Trim und Neuladen
  • Private Bytes: prozessspezifisches Commit
  • Nur Virtual Bytes: Reserve, Mapping, Fragmentierung des Adressraums
  • Nur System Commit: einschließlich anderer Prozesse und der Kernel-Seite
  • Nonpaged Pool: Treiber-/Kernel-Seite
  • Handles / GDI / USER: Lecks bei anderen Ressourcen als Speicher

Überspringen Sie diese Reihenfolge und erstellen Sie sofort einen Dump, landen Sie dabei, eine Menge Informationen über das falsche Ziel zu lesen.

11.4. Zur Aufschlüsselung übergehen

  • Nativer Prozess: VMMap, WinDbg, Application Verifier, Heap-Tracing
  • .NET: dotnet-counters, dotnet-gcdump, dotnet-dump, PerfView
  • Systemweit: RAMMap, PerfMon, WPR/WPA
  • Kernel-Pool: PoolMon, WinDbg

VMMap zeigt den committeten virtuellen Speicher eines Prozesses und das jeweils dafür zugewiesene Working Set nach Typ aufgeschlüsselt an. Wie weit sich das Wachstum bei Private Bytes auf „Heap“, „Private Data“, „Managed Heap“ oder „Mapped File“ eingrenzen lässt, macht für die weiteren Untersuchungskosten einen erheblichen Unterschied.17

11.5. Nach der Korrektur den Verlauf unter denselben Bedingungen vergleichen

Es genügt nicht, dass sich der Spitzenwert vor und nach der Korrektur unterscheidet. Unterscheidet sich der Ausgangswert, kann sich der Vergleich leicht umkehren.

  • Derselbe Startzustand
  • Dieselbe Eingabe
  • Dieselbe Anzahl von Vorgängen
  • Dieselbe Wartezeit
  • Dasselbe Abtastintervall

— und vergleichen Sie danach den Untergrenzwert und den Verlauf nach jedem Zyklus. Der Nachweis einer Leck-Korrektur besteht nicht darin, dass „der Höchstwert kleiner wurde“, sondern darin, dass das Wachstum auch bei wiederholt gleicher Last konvergiert.

12. Häufige Missverständnisse anders formuliert

Missverständnis 1: Der Speicherwert im Task-Manager entspricht der von der App insgesamt zugewiesenen Menge

Anders formuliert: Prüfen Sie, um welche Spalte es sich handelt. Bei der Working-Set-Familie ist es die derzeit im RAM residente Menge, bei der Commit-Size-Familie die diesem Prozess eigene Commit-Menge.

Missverständnis 2: Private Bytes entspricht der Byte-Zahl auf der Auslagerungsdatei

Anders formuliert: Private Bytes ist die private Commit Charge. Es ist eine logisch versprochene Menge, die sowohl Seiten im RAM als auch Seiten umfasst, die bei Bedarf durch die Auslagerungsdatei abgesichert würden.

Missverständnis 3: Commit X/Y entspricht der Nutzung der Auslagerungsdatei / der Kapazität der Auslagerungsdatei

Anders formuliert: X ist die systemweite Commit Charge, Y das Commit Limit. Die Auslagerungsdatei erweitert Y, aber X übersetzt sich nicht unmittelbar in tatsächliche Nutzung auf dem Datenträger.

Missverständnis 4: Ein hoher Wert bei Page Faults/sec bedeutet, dass auf den Datenträger ausgelagert wird

Anders formuliert: Darin sind auch Soft Faults enthalten. Prüfen Sie Pages Input/sec, Page Reads/sec und die Datenträgerlatenz, um festzustellen, ob tatsächlich Datenträger-I/O beteiligt ist.

Missverständnis 5: Wenig freier RAM bedeutet Speichermangel

Anders formuliert: Betrachten Sie Available, Standby, Hard Paging und Antwortzeit. Dass wiederverwendbarer Cache das RAM füllt, ist normal.

Missverständnis 6: Ein verkleinertes Working Set bedeutet, dass ein Speicherleck behoben wurde

Anders formuliert: Möglicherweise wurden lediglich Seiten aus dem RAM verdrängt. Prüfen Sie, ob Private Bytes und die im Heap gehaltenen Referenzen tatsächlich zurückgegangen sind.

Missverständnis 7: Ein Anstieg bei Private Bytes bestätigt ein Leck

Anders formuliert: Das lässt sich erst beurteilen, nachdem Sie geprüft haben, ob es bei Wiederholung derselben Workload konvergiert, welche Art von Speicher gewachsen ist und ob es sich um einen freigebbaren Cache handelt.

13. Zusammenfassung

  • Windows’ „Speicherauslastung“ ist keine einzelne Zahl. Denken Sie Adressraum, Commit, RAM-Residenz und Teilbarkeit getrennt.
  • Working Set sind die derzeit im RAM liegenden Seiten, einschließlich sowohl privater als auch gemeinsamer. Private Working Set sind darunter die prozessspezifischen residenten Seiten.
  • Private Bytes ist die prozessspezifische Commit Charge; sie ist weder die derzeit im RAM liegende Menge noch die tatsächlich in die Auslagerungsdatei geschriebene Menge.
  • Committed X/Y ist die systemweite Commit Charge / das Commit Limit. Die Auslagerungsdatei stützt vor allem das Commit Limit, das Auslagern geänderter Seiten und Absturzabbilder.
  • Eine reservierte virtuelle Adresse, eine committete Seite und eine Seite, die tatsächlich berührt wurde und ins Working Set gelangt ist, sind getrennte Stufen.
  • Ein Page Fault ist normaler Betrieb, und ein Soft Fault liest nicht von der Festplatte. Auch Hard Faults können nicht nur aus der Auslagerungsdatei, sondern auch aus einer EXE, DLL oder Mapped File entstehen.
  • Ein Speicherleck wird nicht anhand der Größe zu einem einzelnen Zeitpunkt bewiesen, sondern anhand des Untergrenzwerts und Verlaufs nach derselben Last, zusammen mit der Aufschlüsselung.
  • Grundsätzlich gilt: VMMap für die Aufschlüsselung eines einzelnen Prozesses, RAMMap für das physische RAM des gesamten Systems, PerfMon für eine Zeitreihe, und ein spezialisiertes Dump-Werkzeug für das, was innerhalb einer Laufzeitumgebung geschieht.

Bemerken Sie das nächste Mal im Task-Manager, dass „der Speicher wächst“, stellen Sie sich zunächst diese Frage.

Wächst das Working Set, Private Bytes, Virtual Bytes oder der System Commit?

Allein diese Frage macht den Einstiegspunkt Ihrer Untersuchung erheblich präziser.

Verwandte Artikel

Verwandte Beratungsleistungen

Die KomuraSoft LLC übernimmt Ursachenuntersuchungen zu wachsendem Speicherverbrauch von Windows-Anwendungen, Leistungseinbußen nach Langzeitbetrieb, OutOfMemory in 32-Bit-Prozessen sowie Speicherengpässen, die nur in der Umgebung eines Kunden auftreten, unter Einsatz von PerfMon, VMMap, RAMMap, WinDbg und .NET-Diagnosewerkzeugen. Wir belassen es nicht bei „der Speicher ist hoch“, sondern grenzen ein, welcher Bereich durch welche Operation warum wächst und von wo aus er referenziert oder gehalten wird.

  1. Microsoft Learn, Working Set. Dazu, dass das Working Set eines Prozesses die Menge der derzeit im physischen Speicher residenten Seiten ist, einschließlich gemeinsam nutzbarer Seiten; zum Unterschied zwischen Soft und Hard Page Faults; zu Transition-Seiten; sowie zum Entfernen von Seiten aus dem Working Set.  2 3 4 5

  2. Microsoft Learn, PROCESS_MEMORY_COUNTERS_EX2 structure. Zu den Definitionen von WorkingSetSize, PrivateWorkingSetSize, PrivateUsage und SharedCommitUsage sowie dazu, dass PagefileUsage und PrivateUsage beide die Commit Charge des Prozesses darstellen.  2 3 4

  3. Microsoft Learn, Introduction to page files. Dazu, dass die Auslagerungsdatei das Auslagern geänderter Seiten, Systemabsturzabbilder und die Erweiterung des System Commit Limit stützt; zu den Definitionen von System Commit Charge und Commit Limit; sowie zur Messung über Task-Manager und Leistungsindikatoren.  2 3 4

  4. Microsoft Learn, Page State. Zu den Zuständen Free, Reserved und Committed einer virtuellen Seite sowie dazu, dass Reserved-Seiten kein zugeordnetes physisches Speicherobjekt besitzen und nicht zugänglich sind.  2

  5. Microsoft Learn, VirtualAlloc function. Zum Unterschied zwischen MEM_RESERVE und MEM_COMMIT; dazu, dass das Committen gegen den Gesamtspeicher und die Auslagerungsdatei des Systems angerechnet wird; sowie dazu, dass die tatsächliche physische Seite unter Umständen erst beim ersten Zugriff zugewiesen wird.  2 3

  6. Microsoft Learn, How to determine the appropriate page file size for 64-bit versions of Windows. Dazu, dass die Größe der Auslagerungsdatei von der Spitzen-Commit-Charge und den Anforderungen an Absturzabbilder abhängt; dazu, dass Hard Page Faults nicht nur von der Auslagerungsdatei, sondern auch von EXE-, DLL- und speicherabgebildeten Dateien lesen; sowie zu den zugehörigen Leistungsindikatoren.  2 3 4 5 6

  7. Microsoft Learn, Virtual Address Space. Dazu, dass jeder Prozess einen eigenen, unabhängigen virtuellen Adressraum und eine eigene Seitentabelle besitzt und eine virtuelle Adresse keine physische Adresse selbst ist. 

  8. Microsoft Learn, Memory Limits for Windows and Windows Server Releases. Dazu, dass der virtuelle Adressraum eines 32-Bit-Prozesses im Benutzermodus normalerweise 2GB beträgt und unter 64-Bit-Windows je nach IMAGE_FILE_LARGE_ADDRESS_AWARE entweder 2GB oder 4GB wird. 

  9. Microsoft Learn, SetProcessWorkingSetSize function. Dazu, dass der minimale und maximale Wert des Working Set keine Residenz garantieren; dazu, dass sich ein Working Set leeren lässt; sowie dazu, dass übermäßige Einstellungen oder Operationen die Systemleistung verschlechtern können. 

  10. Microsoft Learn, Memory Performance Information. Zum Zusammenhang zwischen Windows-Leistungsindikatoren, Speicherverwaltungs-APIs und der Anzeige im Task-Manager, einschließlich Working Set, Working Set - Private und Private Bytes des Process-Objekts sowie Committed Bytes und Commit Limit des System-Objekts. 

  11. Microsoft Learn, MapViewOfFile function. Dazu, dass bei FILE_MAP_COPY jede Seite potenziell Copy-on-write werden kann, weshalb die Commit Charge für die gesamte View bereits beim Mappen reserviert wird, um sie über die Auslagerungsdatei absichern zu können. 

  12. Microsoft Learn, Understanding Node Metrics and Properties in HPC Cluster Manager. Dazu, dass Available Physical Memory als Summe der Listen Zeroed, Free und Standby berechnet wird, sowie zur Bedeutung der einzelnen Seitenlisten. 

  13. Microsoft Sysinternals, RAMMap. Zur Analyse der Nutzung des physischen Windows-Speichers nach Verwendungszweck, Seitenliste, Prozess, Priorität, physischer Seite und Datei.  2

  14. Microsoft Learn, Process.WorkingSet64 Property. Dazu, dass WorkingSet64 das Working Set des Prozesses in Bytes zurückgibt und dem Working-Set-Leistungsindikator des Process-Objekts entspricht. 

  15. Microsoft Learn, Process.PrivateMemorySize64 Property. Dazu, dass PrivateMemorySize64 den nicht mit anderen Prozessen teilbaren, prozesseigenen Speicher zurückgibt und dem Private-Bytes-Leistungsindikator entspricht. 

  16. Microsoft Learn, Process.VirtualMemorySize64 Property. Dazu, dass VirtualMemorySize64 die Menge des dem Prozess zugewiesenen virtuellen Speichers zurückgibt und dem Virtual-Bytes-Leistungsindikator entspricht. 

  17. Microsoft Sysinternals, VMMap. Zur Aufschlüsselung des committeten virtuellen Speichers eines Prozesses nach Typ, zur Anzeige des jeweils zugewiesenen physischen Speichers (Working Set) sowie zu einer detaillierten Speicherzuordnung.  2

Aktuelle Artikel mit denselben Schlagwörtern führen zu verwandten Themen weiter.

Diese Seiten ordnen den Artikel in einen größeren Leistungs- und Entscheidungskontext ein.

Dieser Artikel ist direkt mit den folgenden Leistungen verbunden.

Häufige Fragen

Fragen, die in Beratungen zu diesem Artikelthema häufig gestellt werden.

Zeigt die Spalte „Speicher“ im Task-Manager den gesamten von einer App belegten Speicher?
Nein. Der Task-Manager hat mehrere Speicherspalten — die Working-Set-Familie, die Private-Working-Set-Familie, Commit Size und weitere —, und die Bedeutung hängt davon ab, welchen Bildschirm und welche Spalte Sie betrachten. Working Set sind die Seiten, die derzeit im RAM liegen; Private Bytes oder Commit Size ist die für diesen Prozess spezifische Commit-Menge. Lesen Sie eine einzelne Spalte „Speicher“ nicht als die gesamte von einer App belegte Kapazität oder als Größe eines Lecks.
Was ist der Unterschied zwischen Working Set und Private Bytes?
Working Set ist die Menge der für den Prozess sichtbaren Seiten, die derzeit im physischen RAM resident sind, einschließlich gemeinsam nutzbarer Seiten wie DLL-Code oder speicherabgebildeter Dateien. Private Bytes ist die Menge des ausschließlich von diesem Prozess genutzten committeten Speichers, unabhängig davon, ob er derzeit im RAM resident ist. Beide sind daher nie gleich groß, und keiner der beiden Werte ist durchgängig größer als der andere.
Bedeutet „Committed 18/32GB“ im Task-Manager, dass 18GB in die Auslagerungsdatei geschrieben wurden?
Nein. Der linke Wert ist die Commit-Menge, die das gesamte System derzeit zu unterstützen verspricht, der rechte Wert ist die Commit-Obergrenze, die das System stützen kann. Die Obergrenze ergibt sich grob aus RAM plus Auslagerungsdatei, aber nicht die gesamte linke Summe liegt tatsächlich in der Auslagerungsdatei. Die meisten committeten Seiten liegen im RAM, und manchen committeten Seiten wurde noch nie eine physische Seite zugewiesen. Seiten dagegen, die aus ihrer Ursprungsdatei neu geladen werden können — etwa EXE-, DLL- und speicherabgebildete Dateien —, erhöhen das Working Set nicht zwangsläufig um denselben Betrag wie das private Commit.
Kann OutOfMemory auftreten, obwohl freier RAM verfügbar ist?
Ja. Eine Zuweisung kann aus anderen Gründen als physischem RAM-Mangel fehlschlagen, etwa weil ein 32-Bit-Prozess seinen virtuellen Adressraum erschöpft hat, kein zusammenhängender freier Adressbereich in ausreichender Größe existiert, die System-Commit-Obergrenze erreicht ist oder ein Job-Objekt beziehungsweise die Laufzeitumgebung eine eigene Grenze hat. Insbesondere ein 32-Bit-Prozess unter 64-Bit-Windows ist ohne Large Address Awareness normalerweise auf 2GB virtuellen Adressraum im Benutzermodus begrenzt.
Wird Windows schneller, wenn die Auslagerungsdatei deaktiviert wird?
Im Allgemeinen lässt sich das nicht pauschal bejahen. Das Deaktivieren der Auslagerungsdatei senkt die Commit-Obergrenze des Systems, erschwert das Auslagern ungenutzter geänderter Seiten aus dem RAM und wirkt sich auch auf die Konfiguration von Absturzabbildern aus. Die Größe der Auslagerungsdatei sollte anhand der Spitzen-Commit-Menge und des benötigten Absturzabbilds festgelegt werden — sie ist keine Einstellung, die man ohne Grund deaktiviert.
Bedeutet ein hoher Wert bei Page Faults/sec einen Speichermangel?
Das lässt sich daraus allein nicht entscheiden. Bei Page Faults gibt es Soft Faults, die sich über Standby-Seiten im RAM oder mit einem anderen Prozess gemeinsam genutzte Seiten auflösen lassen, und Hard Faults, die von der Festplatte lesen. Betrachten Sie nicht Page Faults/sec allein, sondern prüfen Sie Pages Input/sec, Page Reads/sec, Available MBytes, die Datenträgerlatenz und die Verarbeitungszeit gemeinsam auf derselben Zeitachse.

Autorenprofil

Profilseite des Artikelautors.

Go Komura

Geschäftsführer von KomuraSoft LLC

Spezialisiert auf Windows-Softwareentwicklung, technische Beratung und Fehleranalyse, insbesondere bei bestehenden Systemen und schwer reproduzierbaren Störungen.

Zurück zum Blog