Question Windows indique que la mémoire vive est épuisée alors qu'il reste 4 Go de mémoire physique disponible


Screenshot of System Information from Process Explorer

Ces informations système proviennent de Process Explorer. Il y a encore de la mémoire physique disponible mais le système ne montre presque plus de mémoire vive.

Le gestionnaire de tâches montre également qu'environ 74% de la mémoire RAM totale est utilisée.

Depuis l'installation de Windows 8.1, l'ordinateur avait 4 + 8 = 12 Go de RAM. Je l'ai mis à niveau en changeant le module de 4 Go en un module de 8 Go. Est-ce que cela pourrait être le problème? Ou est-ce que ce comportement est normal et je viens juste de mal comprendre la signification de la mémoire physique disponible?


20
2017-07-21 04:42


origine


La photo qu'il essayait de joindre est ici: tinypic.com/view.php?pic=npon5c&s=8#.Va3P3_lVhBc  J'ai approuvé une modification pour ajouter cette URL, mais cela ne semble pas suffisant. - Jamie Hanrahan
@JamieHanrahan: Les images doivent être téléchargées en utilisant le Ctrl+G raccourci afin que Stack Exchange puisse les empêcher de pourrir au fil du temps. - Deltik
@Deltik Ce n'était pas mon image à télécharger. - Jamie Hanrahan
@JamieHanrahan - Une fois que la question a été soumise, le matériel a été attribué une licence, l'image est les communautés à ce stade .. - Ramhound
Noté pour référence future, merci. J'ai simplement vu le lien vers le site tinypic dans une édition proposée, et j'ai approuvé cette modification, mais cela n'a eu aucun effet. - Jamie Hanrahan


Réponses:


Réponse courte

La fenêtre contextuelle "Mémoire insuffisante" indique que vous êtes à court de limite de validation - un type de mémoire virtuelle - plutôt que de manquer de mémoire vive (mémoire physique). Peu importe combien disponible RAM que vous avez. Avoir beaucoup de RAM disponible ne vous permet pas de dépasser la limite de validation. La limite de validation est la somme de vos total RAM (en utilisation ou non!) Et sur la taille de votre fichier d'échange actuel.

Réponse intermédiaire

Windows n'a pas réellement de message d'erreur pour manquer de mémoire vive. Ce que vous manquez, c'est "limite de validation".

Le graphe "System" dans cette version de Process Explorer est mal nommé. Il devrait être étiqueté "commettre une charge". (Dans la version, je l'appelle "Commit système". Mieux, mais pas toujours cohérent.) Dans tous les cas, la hauteur "actuelle" du graphique indique ce qui apparaît plus bas dans la section "Commit Charge" - " Current ", et la hauteur maximale du graphique représente" Commit Charge "-" Limit ".

"Commit charge" fait référence à l'espace d'adressage virtuel qui est sauvegardé par le fichier d'échange (si vous en avez un). En d'autres termes, s'il ne peut pas tous tenir dans la RAM, le reste est stocké dans le fichier d'échange. (Il existe d'autres types de canaux qui sont soit soutenus par d'autres fichiers - appelés "mappés" vas - ou qui doivent rester dans la RAM tout le temps, ce dernier est appelé "non pageable".) La "limite de validation" est le maximum la "charge de validation" peut être. Il est égal à votre taille de RAM plus la taille du fichier d'échange.

Vous n'avez apparemment pas de fichier d'échange, donc la limite de validation est simplement la taille de la RAM.

Apparemment, divers programmes + le système d'exploitation ont utilisé presque tout le maximum de validation possible.

Cela n'a rien à voir avec la quantité de RAM disponible ou gratuite. Oui, vous avez environ 4,5 Go de RAM disponibles. Cela ne signifie pas que vous pouvez dépasser la limite de validation. La mémoire validée n'utilise pas nécessairement la RAM et n'est pas limitée par la quantité de mémoire RAM disponible.

Vous devez soit réactiver le fichier d'échange - en l'utilisant beaucoup, je suggère un fichier d'échange de 16 Go, car vous ne voulez pas forcer le système d'exploitation à conserver autant de ces éléments dans la RAM, et le fichier d'échange fonctionne mieux si a beaucoup d'espace libre - ou ajouter plus de RAM. Beaucoup plus. Pour de bonnes performances, vous devez disposer de suffisamment d'espace dans la mémoire vive pour le code et les autres éléments non sauvegardés par le fichier d'échange (mais pouvant être transférés vers d'autres fichiers).

Très longue réponse

(mais toujours beaucoup plus court que le chapitre de gestion de la mémoire de Windows Internals...)

Supposons qu'un programme alloue 100 Mo de mémoire virtuelle privée du processus. Cela se fait avec un appel VirtualAlloc avec l'option "commit". Cela entraînera une augmentation de 100 Mo de la «charge de validation». Mais cette "allocation" n'utilise pas réellement de RAM! La RAM n'est utilisée que lorsque certains de ces nouveaux membres espace d'adressage virtuel est accessible pour la première fois.

Comment la RAM finit par être utilisée

(si c'est le cas)

Le premier accès à l'espace nouvellement engagé serait presque toujours une écriture en mémoire (la lecture de v.a.s. privées nouvellement allouées avant l'écriture est presque toujours une erreur de programmation, puisque son contenu initial est, à proprement parler, indéfini). Mais lisez ou écrivez, le résultat, la première fois que vous touchez une page de v.a.s. défaut de page. Bien que le mot "faute" ne sonne pas bien, les défauts de page sont un événement totalement attendu et même requis dans un système d’exploitation de mémoire virtuelle.

En réponse à ce type de défaut de page, le pager (qui fait partie du gestionnaire de mémoire du système d’exploitation, que je vais parfois abréger en "Mm"):

  1. allouer une page physique de RAM (idéalement à partir de la liste des pages zéro, mais en tout cas, cela provient de ce que Windows appelle "disponible": la liste des pages zéro, libre ou en attente, dans cet ordre de préférence);
  2. remplir un entrée de table de page associer la page physique à la page virtuelle; et enfin
  3. ignorez l'exception de défaut de page.

Après quoi, le code qui a effectué la référence mémoire ré-exécute l'instruction qui a déclenché le défaut de page, et cette fois la référence réussira.

Nous disons que la page a été "mise en défaut" dans le jeu de processus et dans la RAM. Dans le Gestionnaire des tâches, cela apparaîtra comme une augmentation d'une page (4 Ko) dans le «jeu de travail privé» du processus. Et une réduction d'une page dans la mémoire physique disponible. (Ce dernier peut être difficile à remarquer sur une machine occupée.)

Note 1: Cette erreur de page n'implique aucune lecture de disque. Une page de mémoire virtuelle validée jamais consultée ne commence pas sa vie sur le disque. il n'a pas sa place sur le disque pour le lire de. Il est simplement "matérialisé" dans une page de RAM précédemment disponible. Statistiquement, en effet, la plupart des défauts de page sont résolus en RAM, soit sur des pages partagées déjà en RAM pour d’autres processus, soit sur des caches de pages - les listes en attente ou modifiées, ou des pages de type zéro.

Note 2: Cela prend seulement une page, 4096 octets, de "Disponible". L'espace d'adressage validé jamais touché est normalement réalisé en une seule page à la fois, chaque page étant "touchée" pour la première fois. Il n'y aurait aucune amélioration, aucun avantage à faire plus à la fois; cela prendrait juste n fois plus longtemps. En revanche, lorsque des pages doivent être lues à partir du disque, une certaine quantité de "readahead" est tentée, car la grande majorité du temps passé en lecture sur un disque est par opération, et non le transfert de données proprement dit. Le montant "engagé" reste à 100 Mo; le fait qu'une ou plusieurs pages aient été défaillantes ne réduit pas la charge de validation.

Note 3: Supposons que nous ayons 4 Go de RAM "disponibles". Cela signifie que nous pourrions référencer une mémoire engagée déjà allouée mais jamais auparavant référencée environ un million de fois de plus (4 Go / 4096) avant de manquer de mémoire vive. À quel point, si nous avons un fichier de page comme le voulaient David Cutler et Lou Perazzoli, certaines des pages les plus anciennes de la mémoire RAM seraient enregistrées sur le disque puis rendues disponibles pour résoudre ces erreurs de page plus récentes. (En réalité, le système d'exploitation initierait des méthodes de récupération de RAM telles que le «découpage des ensembles de travail» avant et les écritures réelles dans le fichier de page sont mises en cache pour être efficaces et ...) "commis" compte. Il est cependant pertinent de respecter la "limite de validation". S'il n'y a pas de place pour la totalité de la mémoire "engagée" dans la RAM, l'excédent peut être conservé dans le fichier d'échange. Ainsi, la taille du fichier page contribue à la "limite de validation".

Et ça n'arrête pas ...

Mais supposons que nous n'avons pas fait ces millions de références supplémentaires et qu'il reste encore environ 4 Go de pages "disponibles". Maintenant, supposons que le même processus - ou un autre, n’a pas d’importance - fait un autre VirtualAlloc, cette fois par exemple 200 Mo validés. Encore une fois, ces 200 Mo sont ajoutés à la charge de validation, et il ne supprime aucune mémoire vive disponible. L'espace adresse Simply VirtualAlloc'ating n'utilise pas une quantité de RAM correspondante, et le fait d'avoir une faible RAM "disponible" ne limite pas la quantité d'espace d'adressage que vous pouvez VirtualAlloc (ni l'augmentation de la RAM disponible).

(Eh bien, ok ... il y a un tout petit peu trop, une page (paginable!) Qui est utilisée pour une table de pages pour 2 Mo (4 Mo si vous êtes sur un système x86, non-PAE) de espace d'adressage virtuel alloué, et il existe un "descripteur d'adresse virtuelle" de quelques dizaines d'octets pour chaque plage allouée virtuellement contiguë.)

De cette façon, c'est possible - et commun! - utiliser beaucoup de "frais de validation" en n'utilisant que de petites quantités de RAM.

Donc, si "valider" l'espace d'adressage virtuel n'utilise pas de RAM, pourquoi doit-il y avoir une limite?

Parce que la "charge de validation" représente un potentiel avenir utilisation de l'espace de stockage. "Limite de validation" représente la quantité totale de stockage disponible (espace RAM + fichier d'échange) pour contenir ces allocations, devraient-ils jamais être effectivement référencés et de ce fait doivent être stockés quelque part.

Lorsque le Mm approuve une demande VirtualAlloc, il est prometteur - "faire un engagement" - que tous les accès mémoire ultérieurs à la zone allouée réussissent; ils peuvent entraîner des défauts de page, mais les défauts peuvent tous être résolus, car il existe un stockage adéquat pour conserver le contenu de toutes ces pages, que ce soit dans la RAM ou dans le fichier d'échange. Le Mm le sait car il sait combien d'espace de stockage il y a (la limite de validation) et combien a déjà été "engagé" (la charge de validation actuelle).

(Mais on n’a pas encore accédé à toutes ces pages, donc il n’ya pas forcément de stockage pour aller avec le montant engagé, à un moment donné.)

Alors ... Qu'en est-il du "système de mémoire"?

Si vous essayez de VirtualAlloc et que la charge de validation actuelle plus la taille d’allocation demandée vous dépasse la limite de validation ET que le système d’exploitation ne peut pas étendre le fichier de page afin d’augmenter la limite de validation ... up, et le processus voit l'appel VirtualAlloc FAIL. La plupart des programmes se contenteront de lever la main et de mourir à ce moment-là. Certains insisteront aveuglément, en supposant que l'appel a réussi et échouent plus tard lorsqu'ils essaient de référencer la région qu'ils pensaient avoir attribuée.

Encore une fois (désolé pour la répétition): peu importe la quantité de mémoire vive disponible. Le système d’exploitation a promis que la mémoire vive ou l’espace volonté être disponible quand il le faut, mais cette promesse ne se soustrait pas à "Disponible". La RAM disponible n'est utilisée que par les v.m engagés. lorsqu'il est référencé pour la première fois, c'est ce qui provoque son "défaut" ... c'est-à-dire réalisé dans la mémoire physique. Et commettre simplement (= allouer) de la mémoire virtuelle ne fait pas cela. Il ne prend que l'espace d'adressage virtuel libre et rend son espace d'adressage virtuel utilisable.

Mais dans le cas de "mémoire insuffisante", il y a eu une demande d'allocation de mémoire validée, et le système d'exploitation a ajouté la charge de validation actuelle à la taille de cette nouvelle demande ... et a trouvé que le total est plus que la limite de validation. Donc, si l'OS approuvait ce nouveau, et tout cet espace était référencé par la suite, il n'y aurait pas de place réelle (RAM + pagefile) pour tout stocker.

Le système d'exploitation ne permettra pas cela. Il ne permettra pas plus de v.a.s. être alloué qu'il a de la place pour le garder dans le pire des cas - même si tout est "fautif". C'est le but de la "limite de validation".

Je vous dis trois fois que je vous dis trois fois que je vous dis trois fois: La quantité de RAM "disponible" n'a pas d'importance. Que l'espace virtuel engagé n'utilise pas encore tout cet espace de stockage n'a pas d'importance. Windows ne peut pas "s'engager" dans l'allocation virtuelle à moins qu'il ne soit possible de le faire à l'avenir.

Notez qu'il existe un autre type de v.a.s. appelé "mappé", principalement utilisé pour le code et pour accéder à de gros fichiers de données, mais il n'est pas facturé pour "commettre une charge" et n'est pas limité par la "limite de validation". En effet, il dispose de sa propre zone de stockage, les fichiers qui lui sont "mappés". La seule limite sur "mappé" v.a.s. correspond à la quantité d’espace disque disponible pour les fichiers mappés et à la quantité de fichiers v.a.s. dans votre processus pour les cartographier.

Mais quand je regarde le système, je ne suis pas encore à la limite de validation?

C'est essentiellement un problème de mesure et de tenue de dossiers. Vous regardez le système après qu'un appel VirtualAlloc a déjà été essayé et échoué.

Supposons qu'il ne vous reste plus que 500 Mo de limite de validation et que certains programmes aient essayé de VirtualAlloc 600 Mo. La tentative échoue. Ensuite, vous regardez le système et dites "Quoi? Il reste encore 500 Mo!" En fait, il pourrait y en avoir beaucoup plus à ce moment-là, car le processus en question a probablement complètement disparu à ce moment-là, de sorte que TOUTES ses mémoires engagées précédemment allouées ont été libérées.

Le problème est que vous ne pouvez pas regarder en arrière dans le temps et voir ce que la charge de commettre était au moment où la tentative d'allocation a été faite. Et vous ne savez pas non plus combien d'espace était la tentative. Donc, vous ne pouvez pas voir définitivement pourquoi la tentative a échoué, ou combien plus de "limite de validation" aurait été nécessaire pour lui permettre de fonctionner.

J'ai vu "le système est faible courant sur la mémoire ". Qu'est-ce que c'est?

Si dans le cas ci-dessus le système d'exploitation peut étendre le fichier d'échange (c.-à-d. Que vous le laissez au paramètre par défaut "géré par le système" ou que vous le gérez mais que l'espace disque est supérieur au nombre initial, une telle extension augmente suffisamment la limite de validation pour que l'appel VirtualAlloc réussisse, puis ... le Mm développe le fichier d'échange et l'appel VirtualAlloc réussit.

Et c'est quand vous voyez "le système exécute LOW on memory". Ceci est un avertissement précoce que si les choses continuent sans atténuation, vous verrez probablement bientôt un avertissement "de mémoire". Il est temps de fermer certaines applications. Je commencerais par les fenêtres de votre navigateur.

Et vous pensez que c'est une bonne chose? L'expansion du fichier de pages est un mal !!!

Non, ce n'est pas Voir, l'OS ne "développe" pas vraiment le fichier existant. Il ne fait qu'allouer une nouvelle étendue. L'effet ressemble beaucoup à tout autre fichier non contigu. L'ancien contenu de pagefile reste exactement où ils sont; ils ne doivent pas être copiés dans un nouvel endroit ou quelque chose comme ça. Comme la plupart des IO pagefile sont relativement petits par rapport à la taille du fichier d'échange, les chances qu'un transfert dépasse une limite sont très rares, donc la fragmentation ne fait pas de mal à moins qu'elle ne soit vraiment excessive.

Enfin, une fois que tous les processus qui ont "engagé" de l'espace dans l'extension ont quitté (à l'arrêt du système d'exploitation, sinon plus tôt), les extensions sont libérées silencieusement et le fichier d'échange reprend sa taille et son allocation précédentes. est à nouveau

Autoriser l'extension du fichier d'échange agit donc comme un filet de sécurité totalement gratuit: si vous l'autorisez, mais que le système n'en a jamais besoin, le système ne «développera ni ne contractera constamment le fichier d'échange» comme cela est souvent réclamé. rien. Et si jamais vous en avez besoin, cela vous évitera des applications qui se heurtent à des erreurs de mémoire virtuelle.

Mais mais mais ...

J'ai lu sur des dizaines de sites Web que, si vous autorisez l'extension des fichiers d'échange, Windows étendra et contractera constamment le fichier d'échange, ce qui entraînera une fragmentation du fichier d'échange jusqu'à sa défragmentation. 

Ils ont juste tort.

Si vous n'avez jamais vu la "mémoire insuffisante" (ou, dans les anciennes versions, "faible sur la mémoire virtuelle"), le système d'exploitation n'a jamais étendu votre fichier d'échange.

Si vous voyez cette fenêtre contextuelle, cela vous indique que la taille de votre fichier d'échange initial est trop petite. (J'aime définir à environ 4x l'utilisation maximale observée, c'est-à-dire que le compteur de perfmon "% d'utilisation de pagefile" doit être inférieur à 25%. Raison: l'espace fichier de pages est géré comme tout autre segment jouer dedans.)

Mais pourquoi ne font-ils pas que ...

On pourrait soutenir que le système d'exploitation devrait simplement laisser l'allocation se produire et laisser ensuite le les références échec s'il n'y a pas de RAM disponible pour résoudre les défauts de page. En d'autres termes, lorsque nous avons décrit comment fonctionne le défaut de page initial, que se passe-t-il si "l'allocation d'une page physique disponible de RAM" (étape 1) n'a pu être effectuée, et il n'y avait pas de place pour faire quelque chose pour en rendre disponible?

Le téléavertisseur serait alors incapable de résoudre le défaut de page. Il devrait permettre que l'exception (le défaut de page) soit renvoyée au thread défaillant, probablement remplacée par un autre code d'exception.

La philosophie de conception est que VirtualAlloc renverra zéro (techniquement un pointeur NULL) au lieu d'une adresse si la limite de validation est dépassée, et il est tout à fait raisonnable de s'attendre à ce que le programmeur sache qu'un appel VirtualAlloc peut échouer. Ainsi, les programmeurs sont censés vérifier ce cas et faire quelque chose de raisonnable en réponse (comme vous donner une chance de sauvegarder votre travail jusqu’à ce point, puis terminer le programme «gracieusement»). (Programmeurs: vous vérifiez si le pointeur NULL retourne de malloc, new, etc., oui? Alors, pourquoi ne le feriez-vous pas?)

Mais les programmeurs ne devraient pas avoir à s’attendre à ce qu’une simple référence mémoire telle que

i = 0;             // initialize loop counter

peut échouer - pas s'il se trouve dans une région de l'espace d'adressage correctement validé. (Ou mappé espace adresse, d'ailleurs). Mais que se passe-t-il si la philosophie "Autoriser l'allocation de surcroît, laisser la référence de mémoire échouer" a été suivie.

Malheureusement, une référence de mémoire telle que celle figurant dans la ligne de code ci-dessus ne permet tout simplement pas de renvoyer un mauvais statut! Ils sont juste censés travail, tout comme l'addition et la soustraction. La seule façon de signaler de tels échecs serait des exceptions. Donc, pour les gérer, le programmeur devrait envelopper le programme entier dans un gestionnaire d'exceptions. (essayez ... attraper et tout ça.)

Cela peut être fait ... Mais il serait difficile pour le gestionnaire de savoir comment "faire ce qui est juste" en réponse à ces exceptions, car il y aurait beaucoup de points dans le code où ils pourraient se présenter. (Plus précisément, ils pourraient se produire à chaque référence mémoire à la mémoire VirtualAlloc'd, à la mémoire allouée avec malloc ou new ... et à toutes les variables locales également, puisque la pile est également VirtualAlloc.)

En bref, rendre le programme défaillant dans ces cas-là serait très difficile.

Il est assez facile, d'autre part, de vérifier le retour d'un pointeur NULL à partir de VirtualAlloc (ou de malloc ou de new, même si ce n'est pas exactement la même chose) et de faire quelque chose de raisonnable ... sur et faire ce que le programme avait besoin de cet espace virtuel. Et peut-être demander à l'utilisateur s'il veut enregistrer son travail jusqu'à présent, le cas échéant. (Certes, beaucoup trop d’applications ne vous dérangent même pas.)

Autres utilisateurs de commit

Incidemment, la "limite de validation" n'est pas réduite par les différentes allocations du système d'exploitation, telles que les pools paginés et non paginés, la liste PFN, etc. ceux-ci sont simplement chargés de commettre des accusations à mesure qu'elles se produisent. La limite de charge ou de validation de validation n'est pas non plus affectée par la RAM vidéo, ni même la taille de la fenêtre de la RAM vidéo.

Testez-le vous-même

Vous pouvez faire la démonstration de tout cela avec l'outil testlimit du site SysInternals. Option -m allouera l'espace d'adressage engagé mais ne le touchera pas, ce qui n'entraînera pas d'attribution de RAM. Alors que l'option -d allouera et référencera également les pages, entraînant une augmentation de la charge de validation et une diminution de la RAM disponible.

Les références

Windows Internals par Russinovich, Salomon et Ionescu. Il y a même des démonstrations vous permettant de prouver tous ces points en utilisant l'outil testlimit. Cependant, je dois vous avertir que si vous pensez que cela a été long, soyez averti: le chapitre Mm à lui seul compte 200 pages; Ce qui précède est une version extrêmement simplifiée. (Veuillez également consulter la section "Remerciements" de l'introduction.)

Voir également Documentation MSDN VirtualAlloc 


56
2017-07-21 05:00



@AcePL J'ai expliqué pourquoi. En bref: Cela se produit parce que sa limite de validation est trop basse pour sa charge de travail. La limite de validation est la taille totale de la RAM + la taille actuelle du fichier d'échange. La quantité de RAM "disponible" n'y entre pas. Le mécanisme de "limite de validation" n'autorisera pas l'allocation d'espace d'adressage virtuel au-delà de la disponibilité du stockage physique (mémoire de sauvegarde RAM + sur le disque, c'est-à-dire fichier d'échange). Rappelez-vous, même si c'est virtuel, il doit être conservé quelque part une fois qu'il a été endommagé pour la première fois. - Jamie Hanrahan
@AcePL - L'utilisateur n'est pas réellement à court de mémoire. Il est à court de mémoire virtuelle. Cette explication est 100% valide. - Ramhound
@Rahul Basu En fait, je m'attendrais à ce que le court commentaire soit beaucoup plus difficile à comprendre. ;) Cela et de nombreuses questions similaires prouvent que beaucoup de gens ont des idées fausses sur la mémoire virtuelle, les espaces d'adressage, les ensembles de travail, etc. Ce n'est pas de leur faute - c'est un sujet très complexe et les affichages de MS . Mais il faut beaucoup de mots pour expliquer une partie de cela. le Windows Internals a des diagrammes, qui aident. Les diagrammes animés seraient encore meilleurs ... - Jamie Hanrahan
Peut-être intéressant: "il suffit de laisser l'allocation se produire et ensuite laisser les références échouer s'il n'y a pas de RAM disponible pour résoudre les défauts de la page" est similaire à Linux par défaut: Je vais me retrouver à court de mémoire virtuelle pour les pages sales et quand le tueur hors mémoire s’installe… et tue ce qui pourrait être un processus complètement indépendant. Oui, méchant. - Bob
@JamieHanrahan On dirait que tu l'as déjà fait (désolé, c'était un peu occupé). Oui, la surcharge est configurable et certaines distributions le désactiveront. Mais il semble que ce soit encore commun dans 2013 et 2014, et je crois que c'est le noyau par défaut lorsqu'il n'est pas explicitement défini (par distribution ou par utilisateur). - Bob