Que représente réellement la « mémoire utilisée » sous Windows ── Bien lire Working Set, Private Bytes, Commit et le fichier d'échange
· Go Komura · Windows, Développement Windows, Gestion de la mémoire, Working Set, Private Bytes, Commit, Fichier d'échange, Surveillance des performances, Diagnostic d'incidents, Sysinternals
Le Gestionnaire des tâches affiche « 1,2 Go » pour la « mémoire » d’un certain processus. Pourtant, dans Process Explorer, le Working Set indique 1,5 Go, Private Bytes 2,4 Go, et dans VMMap, la Size est encore plus grande. Pour l’ensemble du système, on lit « Committed 19,6/31,8 Go ».
Alors, combien de gigaoctets de mémoire cette application utilise-t-elle réellement ?
La réponse est que le chiffre à consulter dépend de ce que l’on veut savoir. Selon que l’on cherche la quantité actuellement chargée en RAM, l’allocation propre à ce processus, la quantité que le système s’engage à soutenir dans l’avenir, ou simplement la plage d’adresses virtuelles réservée, l’indicateur à regarder n’est pas le même.
Ce qui rend les indicateurs de mémoire de Windows difficiles à comprendre, c’est qu’ils s’affichent tous sous le même mot « mémoire », alors qu’ils mesurent en réalité les axes distincts suivants :
- combien d’espace d’adressage est utilisé
- combien de commit est consommé
- si la page est actuellement résidente en RAM physique
- si cette page est propre au processus ou partageable
- combien d’allocation supplémentaire le système peut encore soutenir dans son ensemble
Cet article s’adresse à ceux qui, sous Windows 10/11 et les versions actuelles de Windows Server, cherchent à comprendre la croissance de la mémoire d’une application ou une pénurie de mémoire à l’échelle du système, et relie en un seul panorama Working Set, Private Working Set, Private Bytes, Commit, Virtual Bytes, le fichier d’échange, Available et les défauts de page.
La procédure pour remonter à la cause d’objets .NET non collectés est traitée dans « Distinguer une attente de GC d’une fuite mémoire en .NET », et les manipulations concrètes de VMMap et Process Explorer dans « Process Explorer / Handle / VMMap en pratique ». Cet article se concentre sur ce qui précède ces démarches : la lecture correcte des chiffres côté système d’exploitation Windows.
1. La conclusion, d’abord
- Working Set désigne les pages actuellement résidentes en RAM. Il inclut non seulement les pages propres au processus, mais aussi les pages partageables avec d’autres processus, comme le code d’une DLL ou un fichier mappé en mémoire.1
- Private Working Set est la partie de Working Set actuellement propre exclusivement à ce processus. Il peut servir d’approximation pour « la RAM que ce processus occupe actuellement en exclusivité », mais il ne représente pas le volume total réservé par l’application.2
- Private Bytes est la quantité de commit propre à ce processus. C’est un indicateur distinct du fait qu’elle soit ou non actuellement chargée en RAM. Le champ
PagefileUsagede la structure Win32 représente aussi, dans les versions actuelles de Windows, essentiellement le même Commit Charge, et non le nombre d’octets réellement écrits dans le fichier d’échange.2 - Le « Committed X/Y » du Gestionnaire des tâches : X est le commit actuel de l’ensemble du système, Y est le plafond de commit. X n’est pas l’utilisation du fichier d’échange. Y est globalement déterminé par la somme de la RAM et du fichier d’échange.3
- Reserve et Commit sont différents. Réserver une adresse virtuelle (Reserve) signifie simplement mettre de côté cette plage pour un usage futur : cela ne consomme ni RAM ni plafond de commit dans la même proportion.45
- Un défaut de page n’implique pas forcément une E/S disque. Il existe des soft faults résolus en RAM, et des hard faults qui lisent depuis le fichier d’échange, un exécutable, ou un fichier mappé en mémoire.16
- Une fuite mémoire se juge sur la pente observée en répétant la même charge, pas sur une valeur unique. Vérifiez en particulier si Private Bytes, ou l’un de ses composants, continue d’augmenter par paliers après la fin du traitement, sans jamais revenir au même état stable.
En une phrase : Working Set est « la quantité actuellement en RAM », Private Bytes est « la quantité promise exclusivement à ce processus », Commit est « la quantité promise par l’ensemble du système ».
flowchart TB
accTitle: Choisir le bon indicateur de mémoire sous Windows
accDescr: L'indicateur à consulter dépend de ce que l'on veut savoir - la quantité résidente en RAM, la commit propre au processus, la commit de l'ensemble du système, ou la plage d'adresses virtuelles
question["Que veut-on savoir avec « utilisation mémoire » ?"]
question -->|"Quantité actuellement en RAM"| workingSet["Working Set"]
question -->|"Quantité promise propre au processus"| privateBytes["Private Bytes"]
question -->|"Quantité promise pour tout le système"| systemCommit["System Commit"]
question -->|"Plage d'adresses réservée"| virtualBytes["Virtual Bytes / Reserved"]
workingSet --> resident["Résidence en RAM physique"]
privateBytes --> privateCommit["Commit propre au processus"]
systemCommit --> commitLimit["Comparaison avec Commit Limit"]
virtualBytes --> addressSpace["Espace d'adressage virtuel"]
Figure 1 : décomposer d’emblée l’observation « il y a beaucoup de mémoire » en quatre questions distinctes.
2. Décomposer « l’utilisation mémoire » en quatre axes
Commençons par considérer la mémoire de Windows non pas comme « une seule barre », mais selon quatre axes.
flowchart TB
accTitle: Les quatre axes indépendants qui classent une page
accDescr: Examiner séparément l'état de l'adresse virtuelle, le support de la page committée, la résidence en RAM physique et la possibilité de partage avec d'autres processus
page["Observer une page selon quatre axes"]
page --> address["État de l'adresse"]
address --> addressValues["Free / Reserved / Committed"]
page --> backing["Support"]
backing --> backingValues["Page-file-backed / File-backed"]
page --> residentAxis["Résidence en RAM"]
residentAxis --> residentValues["Resident / Not resident"]
page --> sharing["Possibilité de partage"]
sharing --> sharingValues["Private / Shareable"]
Figure 2 : pour une même page, l’état de l’adresse, le support, la résidence et le partage se déterminent indépendamment les uns des autres.
Mapped n’est pas un état d’adresse au même rang que Free, Reserved ou Committed : c’est un type de région. Les pages d’une vue mappée peuvent elles aussi être Committed. De même, Private n’est pas un support de stockage mais une catégorie de partageabilité. C’est pourquoi on lit séparément le support (Page-file-backed ou File-backed) et la partageabilité (Private ou Shareable).
En combinant ces quatre axes, on obtient les relations suivantes entre les indicateurs les plus courants.
| État de la page | Working Set | Private Working Set | Private Bytes | Indicateurs Virtual Bytes |
|---|---|---|---|---|
| Propre au processus · Committed · Résidente en RAM | Incluse | Incluse | Incluse | Incluse |
| Propre au processus · Committed · Non résidente en RAM | Exclue | Exclue | Incluse | Incluse |
| Page partagée d’une DLL ou d’un fichier mappé · Résidente en RAM | Incluse | En principe exclue | En principe exclue | Incluse |
| Réservée mais non committée | Exclue | Exclue | Exclue | Peut être incluse |
| Plage d’adresses inutilisée | Exclue | Exclue | Exclue | Généralement exclue |
flowchart TB
accTitle: Correspondance entre les types de pages et les principaux indicateurs de mémoire
accDescr: Montre dans quels indicateurs entrent une page Private résidente, une page Private non résidente, une page partagée résidente et une plage seulement réservée
privateResident["Private · Committed · Résidente en RAM"]
privateNonresident["Private · Committed · Non résidente en RAM"]
sharedResident["Page partagée · Résidente en RAM"]
reservedOnly["Reserved · Non Committed"]
workingSet["Working Set"]
privateWorkingSet["Private Working Set"]
privateBytes["Private Bytes"]
virtualBytes["Indicateurs Virtual Bytes"]
privateResident --> workingSet
privateResident --> privateWorkingSet
privateResident --> privateBytes
privateResident --> virtualBytes
privateNonresident --> privateBytes
privateNonresident --> virtualBytes
sharedResident --> workingSet
sharedResident --> virtualBytes
reservedOnly --> virtualBytes
Figure 3 : Working Set et Private Bytes comptent des ensembles de pages différents, la relation entre eux n’est donc pas une simple inclusion.
Le point important ici est que Working Set et Private Bytes n’entretiennent pas une relation d’inclusion simple.
Private Bytes inclut des pages propres au processus mais actuellement non résidentes en RAM. Working Set, de son côté, inclut des pages partagées non comptées dans Private Bytes, comme le code d’une DLL ou de la mémoire partagée. Il arrive donc, selon le processus ou le moment, que Working Set dépasse Private Bytes, ou l’inverse.
De plus, additionner naïvement le Working Set de plusieurs processus peut compter plusieurs fois la même page physique, par exemple une DLL partagée. « La somme des Working Set de chaque processus = la RAM en usage » n’est donc pas toujours vrai.
3. Espace d’adressage virtuel ── Reserve et Commit sont deux choses différentes
3.1. L’adresse virtuelle n’est pas une adresse de RAM physique
Chaque processus possède son propre espace d’adressage virtuel. Le pointeur manipulé par une application n’indique pas directement un emplacement en RAM physique : Windows fait correspondre les adresses virtuelles à des pages physiques ou à des données sur fichier, via les tables de pages.7
C’est pourquoi, même sur un PC équipé de 64 Go de RAM, l’espace d’adressage virtuel utilisable par un processus 32 bits peut être bien plus petit que cela. À l’inverse, un processus 64 bits disposant d’un espace d’adressage virtuel plus grand que la RAM physique est tout à fait courant.
3.2. Reserved signifie seulement « avoir retenu une adresse »
MEM_RESERVE de VirtualAlloc réserve une plage d’adresses virtuelles contiguë pour un usage futur. À ce stade, aucun stockage physique n’est associé aux pages, et il est impossible de lire ou d’écrire dans cette plage.45
Par exemple, si une base de données ou un runtime réserve (Reserve) une plage d’adresses de 8 Go pour une croissance future, cela seul ne consomme ni 8 Go de RAM ni 8 Go de Private Bytes.
3.3. Committed signifie « promettre de soutenir la page quand elle sera nécessaire »
MEM_COMMIT fait passer la page virtuelle à l’état Committed : c’est l’opération par laquelle Windows s’engage à fournir le support nécessaire. Le fait que la lecture, l’écriture ou l’exécution soient effectivement autorisées se décide séparément, via la protection de page (PAGE_READONLY, PAGE_READWRITE, PAGE_EXECUTE, PAGE_NOACCESS, etc.) : être Committed en soi ne signifie pas « lisible et inscriptible ». Le commit est comptabilisé dans le Commit Charge du système dès cet instant, mais la page physique réelle peut ne pas être attribuée avant le premier accès. Une page touchée pour la première fois est initialisée à zéro, via un Demand-zero fault, avant d’entrer dans le Working Set.51
Il existe donc trois étapes distinctes derrière un même terme « réservé/alloué ».
flowchart TB
accTitle: Les trois étapes de Reserve à Commit puis à la résidence en RAM
accDescr: Montre le flux allant de la réservation de l'adresse virtuelle au commit de la page, puis à l'attribution d'une page physique lors du premier accès et à l'entrée dans le Working Set
reserve["MEM_RESERVE : réservation d'une plage d'adresses"]
reserve -.-> virtualMetric["Reflété dans les indicateurs Virtual Bytes"]
reserve -->|"MEM_COMMIT"| committed["Committed : accessible selon la protection de page"]
committed -.-> commitMetric["Reflété dans Private Bytes / System Commit"]
committed -->|"Premier accès · Demand-zero fault"| resident["Attribution d'une page physique, résidence en RAM"]
resident -.-> workingSetMetric["Reflété dans Working Set"]
committed -.->|"Si jamais accédée"| nonresident["Committed mais non résidente"]
Figure 4 : Reserve, Commit et le premier accès sont des événements distincts, chacun faisant bouger un indicateur différent.
Ces trois étapes font bouger séparément les chiffres de Virtual Bytes, de Private Bytes et de Working Set.
3.4. Pourquoi une erreur OutOfMemory peut survenir alors qu’il reste de la RAM libre
Le succès ou l’échec d’une allocation de mémoire ne dépend pas uniquement de la RAM libre.
- l’espace d’adressage virtuel du processus est épuisé
- il n’existe pas de plage d’adresses libres contiguë de la taille nécessaire
- le Commit Charge de l’ensemble du système a atteint le Commit Limit
- un Job Object, un conteneur, un runtime ou une bibliothèque impose son propre plafond
- le processus est en 32 bits
- le tas natif est fragmenté
Même sous Windows 64 bits, l’espace d’adressage virtuel en mode utilisateur d’un processus 32 bits est en général de 2 Go si IMAGE_FILE_LARGE_ADDRESS_AWARE n’est pas activé. Une application 32 bits ayant activé cet indicateur peut utiliser jusqu’à 4 Go sous Windows 64 bits.8
Il n’y a donc rien de contradictoire à ce que « le PC dispose de 20 Go de RAM libre, mais une application 32 bits échoue aux alentours de 1,6 Go ». Ce n’est pas un problème de RAM, mais probablement une fragmentation de l’espace d’adressage ou l’atteinte d’un plafond.
4. Working Set ── les pages actuellement chargées en RAM
Working Set est l’ensemble des pages de l’espace d’adressage virtuel d’un processus qui sont actuellement résidentes en RAM physique.1
On y trouve un mélange des éléments suivants.
- le tas et la pile propres au processus
- le code et les données en lecture seule des EXE et DLL
- les fichiers mappés en mémoire
- la mémoire partagée
- les pages devenues propres au processus après un copy-on-write
- les pages touchées par le runtime ou diverses bibliothèques
4.1. Une hausse du Working Set ne signifie pas forcément une hausse de l’allocation
Accéder pour la première fois à une page déjà committée peut faire augmenter uniquement le Working Set, sans que Private Bytes ne change. De même, mapper un gros fichier en mémoire et le lire séquentiellement peut faire entrer des pages issues du fichier dans le Working Set, sans presque augmenter Private Bytes.
À l’inverse, lorsque Windows applique un Trim au Working Set en réponse à une pression mémoire, seul le Working Set diminue, alors que l’application conserve logiquement la même mémoire. Y retoucher ultérieurement la fait revenir via un défaut de page.
Une baisse du Working Set ne signifie donc pas forcément « l’application a libéré », ni une hausse « l’application a nouvellement alloué ».
flowchart TB
accTitle: Le schéma typique où seul le Working Set varie
accDescr: La même page committée entre en RAM au premier accès, devient non résidente après un Trim, puis y revient à un nouvel accès, pendant que Private Bytes continue d'être comptabilisé
committed["La même page committée"]
committed -->|"Premier accès"| resident["Résidente en RAM"]
resident -->|"Trim dû à la pression mémoire"| nonresident["Non résidente"]
nonresident -->|"Page Fault au nouvel accès"| resident
resident -.-> inWorkingSet["Incluse dans Working Set"]
nonresident -.-> outsideWorkingSet["Exclue de Working Set"]
committed -.-> privateBytes["Comptabilisée dans Private Bytes tant que committée"]
Figure 5 : le Working Set monte ou descend selon l’état de résidence, mais tant que le commit de la même page subsiste, Private Bytes ne diminue pas.
4.2. Le Working Set inclut des pages partagées
Si 10 processus partagent les mêmes pages de code d’une DLL, ces pages peuvent apparaître dans le Working Set de chacun, alors qu’un seul jeu de pages existe en RAM physique. Que la somme des Working Set dépasse la RAM installée n’est donc pas immédiatement anormal.
Pour se rapprocher de « la RAM que ce processus occupe actuellement en exclusivité », on consulte le Private Working Set. Mais lui non plus ne représente pas « toute la mémoire réservée par ce processus » : ce n’est que la portion de pages Private actuellement résidentes.
4.3. Forcer une réduction du Working Set ne corrige pas une fuite
EmptyWorkingSet ou SetProcessWorkingSetSize permettent d’expulser des pages du Working Set d’un processus. Mais cette opération ne libère ni le commit ni les références détenues dans le tas. Il peut en résulter que l’utilisation apparente de RAM baisse alors que Private Bytes reste inchangé, avec une augmentation des défauts de page au prochain accès.9
Si le chiffre du Gestionnaire des tâches ne baisse que juste après avoir appuyé sur un bouton de « réduction de mémoire », et remonte dès la reprise de l’activité, il s’agit peut-être seulement d’un Trim du Working Set, et non d’une véritable « libération ».
5. Private Bytes ── la commit propre au processus
Private Bytes est la quantité de mémoire virtuelle committée exclusivement pour ce processus. Elle représente le Commit Charge non partageable avec un autre processus, indépendamment de sa résidence actuelle en RAM. Dans la structure PROCESS_MEMORY_COUNTERS_EX de Microsoft, PrivateUsage correspond à cette valeur.102
L’API Win32 comporte aussi un champ au nom trompeur, PagefileUsage, mais la documentation actuelle le définit comme « le Commit Charge de ce processus » et précise qu’il a la même valeur que PrivateUsage. Autrement dit, 2 Go de Private Bytes ne signifient pas « 2 Go écrits dans pagefile.sys ».2
Private Bytes est typiquement influencé par les éléments suivants.
- le commit du tas natif utilisé par
HeapAlloc,malloc,new, etc. - les Private Data committées directement via
VirtualAlloc - les régions committées du tas GC .NET
- la partie effectivement committée de la pile des threads
- pour une vue copy-on-write (
FILE_MAP_COPY), le Commit Charge réservé pour la vue entière au moment du mappage - les tampons privés conservés en interne par des bibliothèques ou des SDK de périphériques
Pour une vue copy-on-write créée avec FILE_MAP_COPY, chaque page pouvant devenir Private dans le futur, Windows réserve dès le mappage un Commit Charge permettant de soutenir toute la vue via le fichier d’échange. Ainsi, même avant qu’une écriture effective ne crée réellement une copie Private, le System Commit et le Commit Charge du processus (Private Bytes) peuvent augmenter de la taille de la vue entière.11
5.1. Pourquoi Private Bytes ne redescend pas après un free ou un passage du GC
Même lorsque l’application « libère » de la mémoire de son point de vue, le runtime ou l’allocateur de tas peut ne pas décommiter cette zone auprès de l’OS et la conserver en vue d’une réutilisation future. Dans ce cas, la zone reste réutilisable en interne pour l’application, mais Private Bytes reste élevé.
De même, une portion vivante seulement partielle d’une grande zone, une fragmentation, ou un cache ou un pool ayant atteint son plafond de préchauffe, peuvent maintenir la valeur élevée.
Un Private Bytes élevé ne prouve donc pas, à lui seul, une fuite. Ce qu’il faut observer, c’est la comparaison suivante dans le temps :
- répéter le même traitement le même nombre de fois
- observer le même temps d’attente après le traitement
- vérifier si Private Bytes revient au même niveau, ou plafonne à une valeur constante
- déterminer, avec VMMap ou un dump de tas, quelle zone ou quel type a augmenté
flowchart TB
accTitle: Pourquoi Private Bytes ne redescend pas après un free ou un passage du GC
accDescr: L'évolution de Private Bytes diffère selon que l'allocateur restitue à l'OS la zone devenue inutile pour l'application, ou la conserve en vue d'une réutilisation
release["L'application libère avec free / GC"]
release --> decision{"L'allocateur restitue-t-il à l'OS ?"}
decision -->|"Decommit / Release"| returned["Le Commit Charge diminue"]
returned --> lower["Private Bytes redescend"]
decision -->|"Conservé pour réutilisation"| retained["La zone reste committée"]
retained --> high["Private Bytes reste élevé"]
retained --> reasons["Pool · cache · fragmentation"]
Figure 6 : qu’une zone soit redevenue réutilisable en interne à l’application n’équivaut pas à la restitution du commit à l’OS.
5.2. Une forme fortement évocatrice d’une fuite
Une croissance « en escalier », où le plancher remonte à chaque charge, comme ci-dessous, mérite l’attention.
Private Bytes
^
| ________
| ______|
| ______|
|_____|
+----------------------------> Répétitions du même traitement
Cela dit, même une forme en escalier peut n’augmenter que quelques fois, du fait du JIT initial, des polices, des décodeurs d’image, des pools de connexion ou de la préchauffe d’un cache, puis se stabiliser. Ce qui compte n’est pas le fait d’augmenter, mais l’absence de convergence vers un état stable.
6. System Commit ── ce que représente vraiment « Committed X/Y »
Le « Committed X/Y » de l’onglet [Performances] → [Mémoire] du Gestionnaire des tâches est un indicateur à l’échelle de l’ensemble du système.
- X : System Commit Charge
la mémoire committée que Windows s’engage actuellement à soutenir pour l’ensemble du système - Y : System Commit Limit
le plafond de commit que le système peut soutenir
Commit Limit est globalement déterminé par la somme de la RAM physique et de tous les fichiers d’échange. En l’absence de fichier d’échange, il est légèrement inférieur à la RAM installée.36
flowchart TB
accTitle: Relation entre System Commit Charge et Commit Limit
accDescr: Le commit propre à chaque processus, celui des sections partagées et celui du noyau composent la valeur actuelle X, tandis que la RAM physique et le fichier d'échange soutiennent le plafond Y
processCommit["Private Commit de chaque processus"] --> charge["System Commit Charge : X"]
sharedCommit["Commit des sections partagées adossées au fichier d'échange"] --> charge
kernelCommit["Commit du noyau"] --> charge
physicalRam["RAM physique"] --> limit["System Commit Limit : Y"]
pageFiles["Fichier d'échange"] --> limit
charge -->|"X ne peut pas dépasser Y"| limit
Figure 7 : X est le montant actuellement promis, Y est le plafond qui permet de soutenir cette promesse ; ce n’est pas un affichage de l’utilisation du fichier d’échange.
System Commit Charge n’inclut pas seulement la somme des Private Bytes de chaque processus, mais aussi le commit des sections partagées adossées au fichier d’échange, ainsi que le commit consommé par le noyau. C’est pourquoi la somme des Private Bytes par processus ne suffit pas, à elle seule, à expliquer entièrement X.
6.1. Le Commit Charge n’est pas l’utilisation du fichier d’échange
Considérons un système avec 16 Go de RAM, 16 Go de fichier d’échange, et un Committed de 20/31 Go.
Ces 20 Go ne signifient pas « 20 Go écrits dans le fichier d’échange ». Ils représentent le montant total pour lequel Windows s’engage à fournir un support — RAM ou fichier d’échange — le moment venu, pour des pages Private modifiables notamment. À cet instant précis coexistent :
- une grande partie résidente en RAM
- une partie déchargée vers le fichier d’échange
- des pages committées mais jamais encore accédées pour la première fois
- une consommation comptabilisée côté commit du noyau
Pour observer l’utilisation réelle du fichier d’échange, il faut vérifier, indépendamment de Commit, Paging File(*)\% Usage. Cela dit, même la documentation de Microsoft précise qu’un taux d’utilisation élevé du fichier d’échange ne signifie pas nécessairement un problème de performance : il faut le juger conjointement avec l’atteinte du Commit Limit, la Modified Page List et les E/S de pagination effectives.6
6.2. Que se passe-t-il en approchant du Commit Limit ?
Lorsque System Commit Charge atteint Commit Limit, le système ne peut plus soutenir de nouvelles demandes de commit. Cela peut entraîner l’échec d’allocations de mémoire côté processus, des plantages d’application, ou une incapacité à opérer.3
Ici, le X/Y du Commit compte davantage que la « RAM libre ». Faire un Trim du Working Set pour créer de la RAM libre ne résout pas l’atteinte du Commit Limit si le Commit Charge lui-même ne diminue pas.
6.3. Les trois rôles du fichier d’échange
Le fichier d’échange remplit principalement les rôles suivants.
- étendre le Commit Limit
- permettre le déchargement hors de la RAM des pages modifiées peu utilisées
- selon la configuration, soutenir le vidage sur incident du système
Désactiver le fichier d’échange ne se traduit pas simplement par une réduction des E/S disque et donc une accélération. Cela peut au contraire abaisser le Commit Limit, rendre plus probable le maintien en RAM de pages modifiées mais inutilisées pour l’instant, et empêcher la capture du vidage nécessaire en cas d’incident.36
La taille appropriée du fichier d’échange ne se détermine pas uniquement à partir de la RAM installée. Microsoft explique lui-même que cela ne peut pas être généralisé, car le pic de System Commit Charge et le type de vidage sur incident nécessaire varient d’un système à l’autre.6
7. La répartition de la RAM physique ── ne pas juger sur la seule faiblesse d’Available
La RAM physique ne sert pas uniquement au Working Set des processus utilisateur.
- le Working Set de chaque processus
- le cache de fichiers système
- les listes de pages Standby, Modified, Free, Zeroed, etc.
- les Paged Pool / Nonpaged Pool du noyau
- la mémoire retenue par les pilotes de périphériques
- le stock de la compression mémoire
- les régions partagées ou réservées avec le GPU ou d’autres périphériques
- les réservations matérielles
7.1. Available inclut aussi du cache réutilisable
Available MBytes de Windows n’est pas une simple mesure de RAM totalement inutilisée. C’est un indicateur qui inclut, en plus de Free et Zeroed, les pages Standby réutilisables en cas de besoin.12
- Free : pages actuellement non attribuées à un usage
- Zeroed : pages remises à zéro pour pouvoir être transmises sans risque à un autre processus
- Standby : pages sorties du Working Set mais dont le contenu reste en cache en RAM
- Modified : pages dont le contenu a été modifié et qui doivent être réécrites vers un support approprié avant réutilisation
flowchart TB
accTitle: Mouvements entre le Working Set et les listes de pages
accDescr: Montre comment une page en cours d'usage bascule vers Standby si elle n'a pas été modifiée, ou vers Modified sinon, puis passe par un nouvel accès, une réécriture ou une réutilisation
workingSet["Working Set : en cours d'usage"]
workingSet -->|"Retrait d'une page non modifiée"| standby["Standby : candidate à la réutilisation, contenu conservé"]
workingSet -->|"Retrait d'une page modifiée"| modified["Modified : en attente de réécriture"]
modified -->|"Réécriture terminée"| standby
standby -->|"Nouvel accès"| workingSet
standby -->|"Réutilisation pour un autre usage"| reused["Attribuée à un autre usage"]
free["Free : inutilisée"] -->|"Mise à zéro"| zeroed["Zeroed : prête à être attribuée"]
zeroed -->|"Accès après attribution"| workingSet
standby -.-> available["Incluse dans Available"]
free -.-> available
zeroed -.-> available
Figure 8 : Available inclut non seulement le libre complet, mais aussi les pages Standby réutilisables en cas de besoin.
« Vider tout le cache pour augmenter la RAM libre » n’est pas toujours avantageux. Si les données nécessaires restent présentes sur Standby, un nouvel accès peut retourner rapidement au Working Set sans lire le disque.
Un Free faible dans le Gestionnaire des tâches, alors qu’Available est suffisant et que les hard page faults ou les attentes disque ne posent pas problème, peut donc simplement signifier que Windows exploite efficacement la RAM comme cache.
7.2. Quand la RAM diminue sans qu’aucun gros processus n’apparaisse
Il n’est pas rare qu’une consommation mémoire ne s’explique pas en additionnant le Private Working Set de chaque processus.
- le cache de fichiers ou les fichiers mappés en mémoire
- les Nonpaged Pool / Paged Pool
- les pages verrouillées par un pilote
- les pages partagées
- la compression mémoire
- les allocations liées à la virtualisation ou au GPU
Dans ce cas, plutôt que de continuer à examiner la liste des processus, on consulte les onglets Use Counts, Processes, Priority Summary et File Summary de RAMMap, l’outil Sysinternals. RAMMap est l’outil officiel pour décomposer la mémoire physique par usage, par liste de pages et par fichier.13
Si seul le Nonpaged Pool continue d’augmenter, c’est le signe qu’il faut suspecter une fuite côté pilote ou noyau, plutôt que dans les Private Bytes d’une application en mode utilisateur.
8. Page Fault ── être fréquent n’est pas anormal en soi
Lorsqu’un processus accède à une page actuellement absente du Working Set, un Page Fault se produit. Malgré le mot « Fault » dans son nom, il ne s’agit pas d’un incident exceptionnel, mais d’un mécanisme normal de fonctionnement de la mémoire virtuelle.1
8.1. Les soft page faults
Ce sont ceux qui se résolvent sans lire le disque.
- la page se trouve encore sur Standby ou en Transition
- une page partagée identique existe dans le Working Set d’un autre processus
- premier accès à une page déjà committée, avec attribution d’une page zéro
- la page se trouve déjà en RAM grâce à la lecture anticipée du gestionnaire de mémoire
C’est pourquoi un \Memory\Page Faults/sec élevé n’implique pas nécessairement des E/S disque ou de la latence.
8.2. Les hard page faults
Ce sont ceux qui nécessitent une lecture du contenu depuis un support de stockage sur disque. La source de lecture ne se limite pas au fichier d’échange.
- le code ou les données d’un
.exeou d’une.dll - un fichier mappé en mémoire
- le fichier d’échange
flowchart TB
accTitle: Bifurcation entre soft page fault et hard page fault
accDescr: Lors d'un accès à une page absente du Working Set, l'absence de besoin d'E/S de stockage donne un soft page fault, sa nécessité donne un hard page fault
access["Accès à une page absente du Working Set"] --> storageIo{"Une E/S de stockage est-elle nécessaire ?"}
storageIo -->|"Non : Standby, partagée, Demand-zero, etc."| soft["Soft page fault"]
soft --> resident["Vers le Working Set sans lire le disque"]
storageIo -->|"Oui"| hard["Hard page fault"]
hard --> source{"D'où lire ?"}
source --> image["EXE / DLL"]
source --> mapped["Fichier mappé en mémoire"]
source --> pagefile["Fichier d'échange"]
image --> loaded["Vers le Working Set après lecture"]
mapped --> loaded
pagefile --> loaded
Figure 9 : le seul nom « Page Fault » ne permet pas de déterminer s’il y a eu ou non une E/S disque.
Microsoft cite \Memory\Pages/sec, \Memory\Page Reads/sec et \Memory\Pages Input/sec comme compteurs permettant de mesurer les hard faults. Un niveau élevé de ces compteurs n’implique pas systématiquement un manque de mémoire : croisez-les avec Available MBytes, la latence disque et le temps de réponse réel.6
8.3. Ne pas fixer de seuil uniforme
Un seuil fixe du type « au-delà de 1000 pour Page Faults/sec, c’est anormal » change de sens selon le stockage, la taille de page, la charge de travail et la localité des accès.
En pratique, alignez les indicateurs suivants sur le même axe temporel :
Memory\Available MBytesMemory\Pages Input/secMemory\Page Reads/sec- la latence de lecture et la file d’attente du disque concerné
- le Working Set et Private Bytes du processus concerné
- le temps de traitement, les délais d’expiration et la réactivité de l’interface de l’application
Si, en même temps qu’une hausse de charge, Available diminue, Pages Input/sec et l’attente disque augmentent, et que le temps de traitement se dégrade également, tous les éléments sont réunis pour suspecter une pagination causée par une pression sur la mémoire physique.
9. Quel écran ou quel outil consulter pour quoi
| Ce que l’on veut savoir | Premier indicateur à consulter | Principaux outils |
|---|---|---|
| La quantité que le processus cible charge actuellement en RAM | Working Set | Gestionnaire des tâches, Process Explorer, Get-Process |
| La part propre au processus dans cette quantité | Private Working Set / Working Set - Private | Colonnes détaillées du Gestionnaire des tâches, Process Explorer, PerfMon |
| La commit propre au processus cible | Private Bytes / Commit Size | Process Explorer, PerfMon, VMMap, Get-Process |
| La plage d’adresses virtuelles du processus | Virtual Bytes / Size | Process Explorer, VMMap, Get-Process |
| La marge de commit de l’ensemble du système | Committed Bytes / Commit Limit | Gestionnaire des tâches [Performances], PerfMon |
| La marge de réutilisation de la RAM physique | Available MBytes | Gestionnaire des tâches, PerfMon |
| La répartition entre Standby, Modified et le cache de fichiers | Répartition par liste de pages et par usage | RAMMap |
| Ce qui a augmenté dans Private Bytes | Heap / Private Data / Managed Heap, etc. | VMMap, WinDbg, dumps propres au runtime |
| La pagination impliquant le disque | Pages Input/sec, Page Reads/sec, latence disque | PerfMon, WPR/WPA |
flowchart TB
accTitle: Choisir l'outil d'investigation mémoire sous Windows
accDescr: L'outil à utiliser dépend du périmètre - un seul processus ou tout le système -, du moment - instantané ou série temporelle -, et du besoin de suivre la rétention interne au runtime
question["Que veut-on isoler ?"]
question --> processScope{"La cible est-elle un seul processus ?"}
processScope -->|"Oui"| processTime{"Instantané ou série temporelle ?"}
processTime -->|"Répartition à un instant donné"| vmmap["VMMap"]
processTime -->|"Série temporelle"| perfmon["PerfMon / PowerShell"]
processScope -->|"Tout le système"| systemView{"Répartition de la RAM physique ou axe temporel ?"}
systemView -->|"Répartition de la RAM physique"| rammap["RAMMap"]
systemView -->|"Axe temporel incluant CPU, E/S, attentes"| wpa["WPR / WPA"]
question --> runtime{"Faut-il suivre la rétention interne au runtime ?"}
runtime -->|"Tas .NET"| dotnet["dotnet-dump / PerfView"]
runtime -->|"Tas natif"| native["WinDbg / Application Verifier"]
Figure 10 : décider d’abord le périmètre et l’axe temporel permet de choisir l’outil nécessaire, sans excès ni manque.
9.1. Le Gestionnaire des tâches
Dans le Gestionnaire des tâches, on consulte des écrans distincts.
- [Processus] ou [Détails] : les familles Working Set et Commit Size de chaque processus
- [Performances] → [Mémoire] : In use, Available, Committed, Cached, Paged pool et Non-paged pool pour l’ensemble du système
Ne jugez pas sur le seul nom de colonne « Mémoire » : dans l’onglet [Détails], faites un clic droit sur l’en-tête de colonne pour ajouter les colonnes nécessaires, comme Working Set, Peak Working Set ou Commit Size. Le nom des colonnes varie légèrement selon la version de Windows et la langue d’affichage : vérifiez le sens de la colonne avant d’enregistrer une mesure.
9.2. Relever une série temporelle avec PowerShell
Si vous connaissez l’ID du processus cible, Get-Process permet de récupérer simultanément l’évolution de Working Set, Private Bytes et Virtual Bytes.
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
Process.WorkingSet64 de .NET correspond à Working Set, PrivateMemorySize64 à Private Bytes, et VirtualMemorySize64 à Virtual Bytes.141516
Pour une application ayant plusieurs instances, suivez-la par PID plutôt que par nom. Pour une surveillance longue durée où le PID change au redémarrage, il faut concevoir un dispositif enregistrant l’heure de démarrage ou le nom du service, afin de ne pas confondre les cibles.
9.3. Aligner système et processus sur le même axe temporel avec PerfMon
Enregistrer simultanément, au minimum, les compteurs suivants facilite l’analyse.
\Process(<cible>)\ID Process
\Process(<cible>)\Working Set
\Process(<cible>)\Working Set - Private
\Process(<cible>)\Private Bytes
\Process(<cible>)\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
En présence de plusieurs processus de même nom, ou en cas de redémarrage pendant la surveillance, le seul nom d’instance Process(nom) ou Process(nom#N) ne permet pas de fixer la cible. Enregistrez aussi ID Process à chaque échantillon, et ne retenez que l’instance dont la valeur correspond au PID suivi. Si un redémarrage fait changer le PID en cours de mesure, notez aussi séparément l’heure du basculement.
Les noms des compteurs de performance de Windows peuvent être localisés selon la langue d’affichage. Si vous indiquez directement en PowerShell un nom anglais introuvable, ajoutez-le depuis l’interface graphique de PerfMon, ou vérifiez les noms de l’environnement local avec Get-Counter -ListSet *.
9.4. Ne pas confondre les rôles de VMMap et de RAMMap
- VMMap : décompose la mémoire virtuelle et le Working Set d’un seul processus en Heap, Image, Mapped File, Private Data, Managed Heap, etc.
- RAMMap : décompose la RAM physique de l’ensemble du système par usage, liste de pages, processus et fichier
« Qu’est-ce qui fait augmenter Private Bytes pour ce processus » relève de VMMap ; « à quoi sert la RAM que la liste des processus n’explique pas » relève de RAMMap.1713
10. Lire les symptômes à partir de combinaisons de chiffres
| Ce qui est observé | Première hypothèse | À vérifier ensuite |
|---|---|---|
| Working Set augmente, Private Bytes est stable | Premier accès à des pages existantes, DLL partagées, fichiers mappés, cache de fichiers | Image / Mapped File dans VMMap, Pages Input/sec |
| Private Bytes augmente, Working Set est stable | Le commit Private a augmenté mais est non résident ou a subi un Trim | Heap / Private Data / Managed Heap dans VMMap |
| Les deux augmentent juste après le démarrage puis se stabilisent | JIT, cache, pool, préchauffe de l’initialisation | Réaugmente-t-il en ajoutant la même charge ? |
| Le plancher de Private Bytes remonte à chaque charge | Fuite, cache sans plafond, allocateur qui retient même après libération | Comparaison de snapshots VMMap avant/après, dump de tas |
| Seul le Working Set chute brutalement puis revient avec l’activité | L’OS ou l’application a fait un Trim du Working Set | Private Bytes, Pages Input/sec, temps de réponse |
| Le X de Committed X/Y se rapproche de Y | Pression de commit à l’échelle du système | Top des Private Bytes, Paged/Nonpaged Pool, configuration du fichier d’échange |
| Available est faible, Pages Input/sec et la latence disque sont élevés | Pression sur la RAM physique et hard paging | Top des Working Set, RAMMap, corrélation avec la charge de travail |
| Le taux d’utilisation RAM est élevé sans gros processus visible | Cache, pages partagées, pool noyau, pilotes, compression, etc. | RAMMap, Pool Nonpaged/Paged Bytes |
| De la RAM libre existe mais seule une application 32 bits échoue | Plafond ou fragmentation de l’espace d’adressage virtuel | Free/Reserved dans VMMap, paramètre LAA de l’exécutable |
| Private Bytes est élevé mais n’augmente pas malgré des répétitions | Pool ou cache maintenant un haut niveau de manière stable | Plafond, état de réutilisation, stabilité après le pic |
Le plus important dans ce tableau, c’est de lire une combinaison, et non une valeur isolée.
11. Procédure pratique d’investigation d’une fuite mémoire
11.1. Fixer d’abord les conditions de reproduction et un point stable
« Ça augmente en quelques jours » ne permet aucune comparaison.
Il faut décider :
- jusqu’où inclure le préchauffage après le démarrage
- le contenu d’un cycle d’opérations
- combien de secondes attendre après un cycle
- combien de répétitions sont nécessaires pour atteindre le plafond du cache
- si la version normale et la version problématique peuvent utiliser la même entrée
11.2. Enregistrer simultanément le processus et le système
Conservez au minimum, aux mêmes instants :
- le Working Set de la cible
- les Private Bytes de la cible
- les Virtual Bytes de la cible
- les Committed Bytes / Commit Limit du système
- Available MBytes
- Pages Input/sec
- le nombre de handles et de threads
- le nombre d’opérations ou d’éléments traités
Si les Private Bytes du processus restent stables alors que le Commit du système continue d’augmenter, il faut élargir le champ de recherche vers d’autres processus, le noyau, les pilotes ou les sections partagées.
11.3. Déterminer d’abord la « dimension » qui augmente
- Working Set seul : pages résidentes, partagées ou issues de fichiers, Trim et rechargement
- Private Bytes : commit propre au processus
- Virtual Bytes seul : Reserve, mappage, fragmentation de l’espace d’adressage
- System Commit seul : inclut aussi d’autres processus et le noyau
- Nonpaged Pool : côté pilotes/noyau
- Handles / GDI / USER : fuite de ressources non liée à la mémoire
Sauter cette étape et capturer directement un dump conduit à examiner une grande quantité d’informations pour une cible mal identifiée.
11.4. Passer à la répartition détaillée
- processus natif : VMMap, WinDbg, Application Verifier, trace de tas
- .NET :
dotnet-counters,dotnet-gcdump,dotnet-dump, PerfView - ensemble du système : RAMMap, PerfMon, WPR/WPA
- pool du noyau : PoolMon, WinDbg
VMMap affiche la mémoire virtuelle committée d’un processus, ainsi que le Working Set attribué à chacune, par type. La capacité à restreindre la hausse de Private Bytes à « Heap », « Private Data », « Managed Heap » ou « Mapped File » change considérablement le coût de l’investigation qui suit.17
11.5. Après une correction, comparer la pente dans les mêmes conditions
Comparer seulement les valeurs de pic avant et après correction ne suffit pas. Une différence de valeur initiale peut facilement inverser le résultat.
Comparez, dans les conditions suivantes :
- le même état de démarrage
- la même entrée
- le même nombre d’opérations
- le même temps d’attente
- le même intervalle d’échantillonnage
le plancher et la pente après chaque cycle. La preuve d’une correction de fuite n’est pas « la valeur maximale a diminué », mais « l’augmentation converge même en répétant la même charge ».
12. Reformuler les malentendus courants
Malentendu 1 : la mémoire du Gestionnaire des tâches = tout ce que l’application a réservé
Reformulation : vérifiez de quelle colonne il s’agit. Pour la famille Working Set, c’est la quantité actuellement résidente en RAM ; pour la famille Commit Size, c’est la commit propre au processus.
Malentendu 2 : Private Bytes = nombre d’octets sur le fichier d’échange
Reformulation : Private Bytes est le Commit Charge Private. C’est un engagement logique qui inclut aussi bien les pages en RAM que celles que le fichier d’échange pourrait soutenir en cas de besoin.
Malentendu 3 : Commit X/Y = utilisation du fichier d’échange / taille du fichier d’échange
Reformulation : X est le Commit Charge de l’ensemble du système, Y est le Commit Limit. Le fichier d’échange étend Y, mais X ne se traduit pas directement par une utilisation sur disque.
Malentendu 4 : un Page Faults/sec élevé = un swap vers le disque
Reformulation : cela inclut aussi les soft faults. Pour savoir si une E/S disque est impliquée, vérifiez Pages Input/sec, Page Reads/sec et la latence disque.
Malentendu 5 : peu de Free RAM = manque de mémoire
Reformulation : observez Available, Standby, le hard paging et le temps de réponse. Remplir la RAM avec du cache réutilisable est normal.
Malentendu 6 : réduire le Working Set = corriger une fuite mémoire
Reformulation : cela peut n’avoir fait qu’expulser des pages de la RAM. Vérifiez si Private Bytes ou la rétention dans le tas a réellement diminué.
Malentendu 7 : Private Bytes a augmenté = fuite confirmée
Reformulation : on ne peut juger qu’après avoir vérifié si cela converge en répétant la même charge de travail, quel type de mémoire a augmenté, et s’il s’agit d’un cache libérable.
13. Conclusion
- « L’utilisation mémoire » de Windows n’est pas un chiffre unique. Il faut distinguer l’espace d’adressage, le commit, la résidence en RAM et la partageabilité.
- Working Set désigne les pages actuellement en RAM, incluant à la fois Private et Shared. Private Working Set en est la partie propre au processus, parmi les pages résidentes.
- Private Bytes est le Commit Charge propre au processus : ni la quantité actuellement en RAM, ni la quantité réellement écrite sur le fichier d’échange.
- Committed X/Y correspond au Commit Charge / Commit Limit de l’ensemble du système. Le fichier d’échange soutient principalement le Commit Limit, le déchargement des pages modifiées et le vidage sur incident.
- L’adresse virtuelle réservée, la page committée, et la page réellement touchée et entrée dans le Working Set sont des étapes distinctes.
- Un Page Fault relève du fonctionnement normal ; le soft fault ne lit pas le disque. Le hard fault peut se produire non seulement à partir du fichier d’échange, mais aussi d’un EXE, d’une DLL ou d’un fichier mappé.
- Une fuite mémoire se prouve non par une taille observée à un instant donné, mais par le plancher et la pente après une même charge répétée, ainsi que par la répartition détaillée.
- Pour la répartition d’un processus individuel, utilisez VMMap ; pour la RAM physique de l’ensemble du système, RAMMap ; pour une série temporelle, PerfMon ; et pour l’intérieur du runtime, les outils de dump dédiés.
La prochaine fois que vous remarquez dans le Gestionnaire des tâches que « la mémoire augmente », reformulez d’abord ainsi la question :
Ce qui augmente, est-ce le Working Set, Private Bytes, Virtual Bytes, ou le System Commit ?
Cette seule question rend l’entrée en matière de l’investigation nettement plus précise.
Articles connexes
- Distinguer une attente de GC d’une fuite mémoire en .NET ── procédure pratique pour observer, comparer et prouver une croissance de mémoire
- Process Explorer / Handle / VMMap en pratique ── remonter un blocage, une fuite ou un « fichier en cours d’utilisation » à partir de l’état présent
- Pièges et bonnes pratiques de la mémoire partagée ── concevoir en toute sécurité un partage entre processus sous Windows
- L’écriture différée du Cache Manager de Windows ── de WriteFile jusqu’à l’inscription sur disque
- Causes et parades des plantages après un fonctionnement prolongé dus à une fuite de handles dans une application Windows
Domaines de conseil associés
合同会社小村ソフト (Komura Software LLC) prend en charge l’investigation des causes de croissance mémoire des applications Windows, de dégradation des performances après un fonctionnement prolongé, d’OutOfMemory sur un processus 32 bits, et de pénuries mémoire ne se produisant que chez le client, en combinant PerfMon, VMMap, RAMMap, WinDbg et les outils de diagnostic .NET. Nous ne nous arrêtons pas à un simple constat de « beaucoup de mémoire » : nous isolons quelle zone, par quelle opération, pourquoi elle augmente, et depuis où elle est référencée ou retenue.
- Développement d’applications Windows
- Investigation de bugs et analyse de cause
- Conseil technique et revue de conception
- Contact
Références
-
Microsoft Learn, Working Set. Sur le fait que le Working Set d’un processus est l’ensemble des pages actuellement résidentes en mémoire physique, qu’il inclut des pages partagées, sur la différence entre soft et hard page faults, les pages en Transition, et le retrait de pages du Working Set. ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, PROCESS_MEMORY_COUNTERS_EX2 structure. Sur les définitions de WorkingSetSize, PrivateWorkingSetSize, PrivateUsage et SharedCommitUsage, et sur le fait que PagefileUsage et PrivateUsage représentent tous deux le Commit Charge du processus. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Introduction to page files. Sur le fait que le fichier d’échange soutient le déchargement des pages modifiées, le vidage sur incident du système et l’extension du System Commit Limit, sur les définitions de System Commit Charge et Commit Limit, et sur leur mesure via le Gestionnaire des tâches et les compteurs de performance. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Page State. Sur les états Free, Reserved et Committed d’une page virtuelle, et sur le fait qu’aucun stockage physique n’est associé à une page Reserved, la rendant inaccessible. ↩ ↩2
-
Microsoft Learn, VirtualAlloc function. Sur la différence entre MEM_RESERVE et MEM_COMMIT, le fait que le Commit soit comptabilisé (Charge) dès l’appel sur la mémoire système et le fichier d’échange, et le fait que la page physique réelle puisse n’être attribuée qu’au premier accès. ↩ ↩2 ↩3
-
Microsoft Learn, How to determine the appropriate page file size for 64-bit versions of Windows. Sur le fait que la taille du fichier d’échange dépend du pic de Commit Charge et des besoins en vidage sur incident, que la source de lecture des hard page faults ne se limite pas au fichier d’échange mais inclut aussi EXE, DLL et fichiers mappés en mémoire, et sur les compteurs de performance associés. ↩ ↩2 ↩3 ↩4 ↩5 ↩6
-
Microsoft Learn, Virtual Address Space. Sur le fait que chaque processus possède son propre espace d’adressage virtuel et ses propres tables de pages, et que l’adresse virtuelle n’est pas l’adresse physique elle-même. ↩
-
Microsoft Learn, Memory Limits for Windows and Windows Server Releases. Sur le fait que l’espace d’adressage virtuel en mode utilisateur d’un processus 32 bits est en général de 2 Go, et qu’il devient 2 Go ou 4 Go sous Windows 64 bits selon la présence d’IMAGE_FILE_LARGE_ADDRESS_AWARE. ↩
-
Microsoft Learn, SetProcessWorkingSetSize function. Sur le fait que les valeurs minimale et maximale du Working Set ne garantissent pas la résidence, que le Working Set peut être vidé, et qu’un réglage ou une opération excessifs peuvent dégrader les performances du système. ↩
-
Microsoft Learn, Memory Performance Information. Sur la correspondance entre les compteurs de performance de Windows, les API de gestion de la mémoire et les affichages du Gestionnaire des tâches, ainsi que sur Working Set, Working Set - Private, Private Bytes du processus, et Committed Bytes, Commit Limit du système. ↩
-
Microsoft Learn, MapViewOfFile function. Sur le fait qu’avec
FILE_MAP_COPY, toutes les pages pouvant devenir copy-on-write, un Commit Charge est réservé dès le mappage pour soutenir la vue entière via le fichier d’échange. ↩ -
Microsoft Learn, Understanding Node Metrics and Properties in HPC Cluster Manager. Sur le fait qu’Available Physical Memory se calcule comme la somme des listes Zeroed, Free et Standby, et sur la signification de chacune de ces listes de pages. ↩
-
Microsoft Sysinternals, RAMMap. Sur la fonction d’analyse de l’utilisation de la mémoire physique de Windows par usage, liste de pages, processus, priorité, page physique et fichier. ↩ ↩2
-
Microsoft Learn, Process.WorkingSet64 Property. Sur le fait que
WorkingSet64renvoie le Working Set du processus en octets, correspondant au compteur de performance Working Set du processus. ↩ -
Microsoft Learn, Process.PrivateMemorySize64 Property. Sur le fait que
PrivateMemorySize64renvoie la mémoire propre au processus, non partageable avec d’autres processus, correspondant au compteur de performance Private Bytes. ↩ -
Microsoft Learn, Process.VirtualMemorySize64 Property. Sur le fait que
VirtualMemorySize64renvoie la quantité de mémoire virtuelle du processus, correspondant au compteur de performance Virtual Bytes. ↩ -
Microsoft Sysinternals, VMMap. Sur la fonction de décomposition par type de la mémoire virtuelle committée d’un processus, avec le Working Set attribué à chacune et une cartographie mémoire détaillée. ↩ ↩2
Articles associés
Articles récents partageant les mêmes étiquettes, pour approfondir des sujets proches.
Utiliser WMI/CIM depuis C# et PowerShell — Guide pratique pour la récupération d'informations matérielles, la surveillance des processus et l'interrogation à distance
La récupération du numéro de série d'un PC, la surveillance de l'espace disque libre et la détection du démarrage de processus reposent c...
Process Explorer / Handle / VMMap en pratique — Diagnostiquer les blocages, fuites et « fichiers en cours d'utilisation » à partir de l'état du système à cet instant précis
Deuxième volet pratique de la série Sysinternals pour diagnostiquer « ça ralentit progressivement », « impossible de supprimer un fichier...
Guide pratique de Process Monitor (ProcMon) — identifier en 10 minutes un « paramètre non pris en compte » ou un ACCESS DENIED
« J'ai corrigé le fichier de configuration, mais rien ne change » ; « ça marchait hier, mais ça ne démarre plus aujourd'hui » — avant de ...
Empêcher les lancements multiples d'une application Windows — Mutex nommé et activation de la fenêtre existante lors d'un second lancement
Cet article détaille comment implémenter la prévention des lancements multiples d'une application Windows métier à l'aide d'un Mutex nomm...
Externalisation et développement sur mesure d'une application Windows : ce qu'il faut clarifier avant de se lancer
Avant de confier l'externalisation ou le développement sur mesure d'une application Windows, voici les points à clarifier : révision d'un...
Sujets associés
Ces pages replacent le sujet dans un contexte plus large de services et de décisions.
Thèmes techniques Windows
Portail des sujets sur le développement Windows, l'analyse des incidents et la valorisation des actifs existants.
Services liés à ce sujet
Cet article est directement lié aux services suivants.
Développement d'applications Windows
Applications métier, intégration d'équipements et outils de communication, des besoins au développement.
Questions fréquentes
Questions souvent posées lors d’une consultation sur le sujet de cet article.
- La « mémoire » affichée par le Gestionnaire des tâches est-elle toute la mémoire réservée par l'application ?
- Non. Le Gestionnaire des tâches propose plusieurs colonnes de mémoire — la famille Working Set, la famille Private Working Set, Commit Size — et le sens change selon l'écran et la colonne consultés. Working Set désigne les pages actuellement chargées en RAM, tandis que Private Bytes ou Commit Size représentent la quantité de commit propre à ce processus. Ne lisez jamais une unique colonne « mémoire » comme la capacité totale réservée par l'application ni comme le volume d'une fuite.
- Quelle est la différence entre Working Set et Private Bytes ?
- Working Set est la quantité de pages visibles depuis ce processus et actuellement résidentes en RAM physique, y compris les pages partagées comme les DLL ou les fichiers mappés en mémoire. Private Bytes est la quantité de mémoire committée utilisée exclusivement par ce processus, qu'elle soit ou non actuellement résidente en RAM. Les deux valeurs ne coïncident donc jamais, et il n'existe pas de relation d'ordre simple entre elles.
- « Committed 18/32 Go » dans le Gestionnaire des tâches signifie-t-il que 18 Go ont été écrits dans le fichier d'échange ?
- Non. Le nombre de gauche est la quantité de commit actuellement promise par l'ensemble du système, le nombre de droite est le plafond de commit que le système peut soutenir. Ce plafond est globalement déterminé par la somme de la RAM et du fichier d'échange, mais le total de gauche ne se trouve pas intégralement sur le fichier d'échange. La plupart des pages committées sont en RAM, et certaines n'ont encore jamais reçu de page physique. À l'inverse, les pages qui peuvent être rechargées depuis leur fichier d'origine — comme celles d'un EXE, d'une DLL ou d'un fichier mappé en mémoire — n'augmentent pas nécessairement le Commit privé dans la même proportion que le Working Set.
- Peut-on obtenir une erreur OutOfMemory alors qu'il reste de la RAM libre ?
- Oui, cela arrive. L'insuffisance de l'espace d'adressage virtuel d'un processus 32 bits, le manque de plage d'adresses libres contiguës, le plafond de commit du système, ou des plafonds propres à un Job Object ou à un runtime sont autant de conditions d'échec d'allocation indépendantes de la RAM physique. En particulier, un processus 32 bits sous Windows 64 bits est en général limité à 2 Go d'espace d'adressage virtuel en mode utilisateur, sauf s'il est Large Address Aware.
- Désactiver le fichier d'échange rend-il Windows plus rapide ?
- On ne peut pas l'affirmer en général. Désactiver le fichier d'échange abaisse le plafond de commit du système, rend plus difficile le déchargement hors de la RAM des pages modifiées mais inutilisées, et affecte aussi la configuration des vidages sur incident. La taille du fichier d'échange doit être décidée en mesurant le pic de commit et les besoins en vidage sur incident ; ce n'est pas un paramètre à désactiver sans justification.
- Un Page Faults/sec élevé signifie-t-il un manque de mémoire ?
- Ce seul indicateur ne permet pas de le déterminer. Les défauts de page se répartissent entre les soft faults, résolus par une page Standby en RAM ou partagée avec un autre processus, et les hard faults, qui nécessitent une lecture depuis le disque. Ne vous fiez pas à Page Faults/sec isolément : croisez-le avec Pages Input/sec, Page Reads/sec, Available MBytes, la latence disque et le temps de traitement sur le même axe temporel.
Profil de l’auteur
Page de présentation de l’auteur de l’article.
Go Komura
Représentant de KomuraSoft LLC
Spécialisé dans le développement de logiciels Windows, le conseil technique et l’analyse de pannes, notamment pour les systèmes existants et les incidents difficiles à reproduire.