C # app simple créer un nombre énorme de défauts de page. Pourquoi?

Avoir une simple application console C # qui importe des données texte dans SQL.

Il faut environ 300K en mémoire et 80% en CPU. Il y a 2 Go de RAM disponible à tout moment et pourtant le défaut de page montre 500K.

L’application est 32 bits et le système d’exploitation est W2000 ou XP 32 bits et .NET 3.5

Tout le monde peut expliquer ce qui pourrait être le problème et comment puis-je enquêter plus avant?

EDIT: Je suis maintenant certain que les défauts de la page sont liés aux E / S du disque (read). J’ai commenté la partie SQL et la lecture pure du disque génère ce nombre élevé seul.

EDIT2: Il y a en moyenne 200 défauts / sec et 4000 défauts faibles / sec.

Je me demande si la même chose apparaîtrait sur W2008

Tout d’abord, comment mesurez-vous la mémoire utilisée par l’application? Si vous regardez “ensemble de travail”, c’est seulement la partie qui réside dans la mémoire physique. Vous devriez également regarder le “VM Size” (ou “Commit Size”) où se trouve la mémoire virtuelle réelle de votre processus.

Si le gestionnaire de jeu de balises du kernel Windows pense que votre application est inactive ou devrait être laissée pour donner plus de puissance aux autres processus, elle peut décider de réduire la taille de l’ensemble de travail. Si la taille du jeu de travail est inférieure à celle sur laquelle votre application doit réellement fonctionner, vous pouvez facilement voir de nombreuses erreurs de page car cela devient simplement une course entre The Balance Set Manager et l’application. Habituellement, le gestionnaire du jeu de balances surveille l’utilisation de la mémoire et peut également décider d’augmenter la taille des ensembles de travail en conséquence. Cependant, cela peut être évité dans certaines circonstances, comme une faible mémoire physique, des E / S élevées (stress de la mémoire physique dans la mémoire cache), une faible priorité au processus, l’état de fond / avant-plan de l’application, etc.

Cela peut simplement être le comportement du ramasse-miettes .NET en raison de la grande quantité de petits blocs de mémoire alloués et éliminés en très peu de temps, ce qui provoque une contrainte sur l’allocation de mémoire et la libération. La “VM Size” pouvait restr à peu près la même taille, mais dans les coulisses, elle pouvait continuellement allouer / libérer de la mémoire, provoquant des défauts de page continus.

Sachez également que les DLL utilisées par le processus sont également sockets en compte pour les statistiques de processus. Votre application, à l’exception de l’une des DLL COM ou .NET que vous utilisez, peut également être à l’origine de ce problème. Vous pouvez déduire le véritable coupable en modifiant le comportement de votre application (par exemple, en supprimant le code d’access à la firebase database et en ne laissant que le code d’affectation d’object) pour voir quel composant provoque effectivement une violation.

EDIT: À propos de votre question sur l’impact du GC sur la mémoire en mémoire vive: le CLR fait croître le tas dynamicment et redonne la mémoire au système d’exploitation si nécessaire . Cela ne se produit pas de manière synchrone. Le GC s’exécute en arrière-plan et libère de la mémoire en gros morceaux pour empêcher les performances de l’application. Disons que vous allouez beaucoup de petits objects et que vous les libérez presque immédiatement. Cela provoque de nombreuses références à restr un moment en mémoire avant de les libérer. Il est facile d’imaginer que cela devient comme une course face à face entre le garbage collector et le code d’allocation de mémoire. Alors que GC rattrape éventuellement, la nouvelle mémoire requirejse doit être satisfaite à partir d’une “nouvelle mémoire”, pas de l’ancienne, car l’ancienne n’est pas encore libérée. La mémoire réelle sur laquelle nous travaillons rest inchangée, le gestionnaire de jeu de balances ne pense peut-être pas à donner plus de mémoire à notre processus car nous sums toujours à la même taille de mémoire physique, mais nous avons mémoire “, donc des défauts de page.

Les défauts de page sont normaux. La mémoire est remplacée et lorsque vous accédez ensuite à une erreur de page et que le système le ramène. C’est par conception.

J’ai une application en cours d’exécution sur ma machine en ce moment avec 500 millions de défauts de page. Aucune raison de s’inquiéter!

Les défauts de page signifient des problèmes de mémoire

Envisagez d’augmenter la mémoire si vous avez trop de défauts de page.

Avoir une grande taille de travail.

L’ensemble de travail est l’ensemble des pages de mémoire actuellement chargées dans la RAM. Ceci est mesuré par Process \ Working Set. Une valeur élevée peut indiquer que vous avez chargé plusieurs assemblys.

Process \ Working Set n’a pas de valeur de seuil spécifique à surveiller, bien qu’une valeur élevée ou fluctuante puisse indiquer un manque de mémoire. Une valeur élevée ou fluctuante accompagnée d’un taux élevé de défauts de page indique clairement que votre serveur n’a pas assez de mémoire.

Lectures complémentaires:

Vérifiez la mémoire sous Ressources système dans l’article MSDN suivant: http://msdn.microsoft.com/en-us/library/ff647791.aspx#scalenetchapt15_topic9

Veuillez fournir un code pour enquêter.

Une réponse possible à cela, je le teste actuellement sur mon application. Divisez votre travail en petits morceaux et travaillez avec les morceaux.

Par exemple, j’ai une grande liste d’objects (9000-30000). Si je divise cette liste en quelque 500 morceaux à la fois, elle devrait conserver les 500 objects en mémoire pendant que je les travaille.

Vous voudrez augmenter ou diminuer la taille de votre morceau jusqu’à ce que vous puissiez travailler avec suffisamment rapidement pour que le système d’exploitation le conserve en mémoire. C’est la théorie que je n’ai pas encore entièrement testée. Mais ça devrait marcher.