Éléments rapides à case activée lorsque vous rencontrez des niveaux de mémoire élevés dans ASP.NET

Cet article décrit les étapes rapides à case activée lorsque vous rencontrez une mémoire élevée dans Microsoft ASP.NET.

              Version d’origine du produit : ASP.NET
Numéro de la base de connaissances d’origine : 893660

Cet article commence par des problèmes courants, des actions pour y remédier et une brève explication de la raison pour laquelle ces situations peuvent causer des problèmes.

ASP.NET colonne Support Voice

Dans la colonne Support Voice d’avril 2005, nous avons fourni par inadvertance un lien vers le fichier incorrect. Au lieu d’établir un lien vers un téléchargement pour le service Web, nous avons lié au fichier XML retourné par le service Web. Ce lien a été corrigé. Si vous souhaitez consulter l’article avec le fichier correct joint, consultez Mises à jour de pages dynamiques à l’aide de XMLHTTP.

Ce qui est considéré comme une mémoire élevée

Évidemment, cette question dépend du volume et de l’activité de certaines applications. En général, la mémoire élevée est lorsque votre mémoire de processus de travail ASP.NET (Aspnet_wp.exe) ou de processus de travail IIS (W3wp.exe) augmente constamment et ne revient pas à un niveau confortable.

En général, un niveau confortable serait inférieur à 600 Mo dans l’espace d’adressage de mémoire utilisateur par défaut de 2 Go. Une fois que le niveau de mémoire est supérieur à ce niveau confortable, nous faisons moins que ce que nous devrions être. Ce comportement peut affecter d’autres applications qui s’exécutent sur le système.

L’essentiel est de comprendre que certaines applications nécessitent plus de mémoire que d’autres. Si vous dépassez ces limites, vous pouvez ajouter plus de mémoire ou ajouter un autre serveur à votre batterie de serveurs Web (ou envisager une batterie de serveurs Web). Le profilage est également recommandé dans ces cas. Il peut permettre aux développeurs de créer des applications plus simples. Dans cet article, nous examinons une situation dans laquelle la mémoire augmente constamment jusqu’à ce que le serveur cesse de fonctionner.

Configuration de l’application pour le débogage

L’une des raisons de la mémoire élevée que nous voyons ici dans Support est lorsque le débogage, le suivi ou les deux sont activés pour votre application. L’activation du débogage et du suivi est une nécessité lorsque vous développez votre application. Par défaut, lorsque vous créez votre application dans Visual Studio .NET, vous voyez l’attribut suivant défini dans votre fichier Web.config :

<compilation
 ...
 debug="true"
 />

ou

 <trace
 enabled="true"
 ...
 />

En outre, lorsque vous effectuez une build finale de votre application, assurez-vous de le faire en mode Mise en production, et non en mode Débogage. Une fois que vous êtes en production, le débogage ne doit plus être nécessaire. Il peut vraiment ralentir votre performance et manger votre mémoire. La définition de cet attribut signifie que vous modifiez quelques éléments sur la façon dont vous gérez votre application.

Tout d’abord, la compilation par lots est désactivée, même si elle est définie dans cet compilation élément. Cela signifie que vous créez un assembly pour chaque page de votre application afin de pouvoir y pénétrer. Ces assemblys peuvent être dispersés de manière aléatoire dans votre espace mémoire, ce qui rend plus difficile la recherche de l’espace contigu pour allouer de la mémoire.

Deuxièmement, l’attribut executionTimeout (<élément httpRuntime>) est défini sur un nombre élevé, remplaçant la valeur par défaut de 90 secondes. C’est très bien lors du débogage, car vous ne pouvez pas avoir le délai d’attente de l’application pendant que vous parcourez patiemment le code pour trouver vos erreurs. Toutefois, il s’agit d’un risque important en production. Cela signifie que si vous avez une demande malveillante pour une raison quelconque, elle conservera un thread et continuera tout comportement préjudiciable pendant des jours au lieu de quelques minutes.

Enfin, vous allez créer d’autres fichiers dans votre dossier Fichiers ASP.NET temporaires . Et l’espace System.Diagnostics.DebuggableAttribute de noms (System.Diagnostics Namespace ) est ajouté à tout le code généré, ce qui peut entraîner une dégradation des performances.

Si vous n’obtenez rien d’autre de cet article, j’espère que vous obtenez cette information. Laisser le débogage activé est incorrect. Nous voyons ce comportement trop souvent, et il est si facile de changer. N’oubliez pas qu’elle peut être définie au niveau de la page. Assurez-vous que toutes vos pages ne le définissent pas.

Concaténation de chaînes

Il existe des applications qui génèrent une sortie HTML à l’aide de code côté serveur et en créant simplement une chaîne HTML volumineuse à envoyer au navigateur. C’est bien, mais si vous créez la chaîne à l’aide + de et & de la concaténation, vous ne savez peut-être pas combien de grandes chaînes vous créez. Par exemple :

string mystring = "<html>";
mystring = mystring + "<table><tr><td>";
mystring = mystring + "First Cell";
mystring = mystring + "</td></tr></table>";
mystring = mystring + "</html>";

Ce code semble suffisamment inoffensif, mais voici ce que vous stockez en mémoire :

<html>
<html><table><tr><td>
<html><table><tr><td>First Cell
<html><table><tr><td>First Cell</td></tr></table>
<html><table><tr><td>First Cell</td></tr></table></html>

Vous pensez peut-être que vous stockez simplement la dernière ligne, mais vous stockez toutes ces lignes. Vous pouvez voir comment cela peut se passer de la main, en particulier lorsque vous créez une grande table, peut-être en effectuant une boucle dans un jeu d’enregistrements volumineux. Si c’est ce que vous faites, utilisez notre System.Text.StringBuilder classe, afin de stocker simplement la seule chaîne de grande taille. Consultez Utiliser Visual C# pour améliorer les performances de concaténation de chaînes.

.NET Framework Service Pack 1 (SP1)

Si vous n’exécutez pas encore .NET Framework SP1, installez ce fournisseur de services si vous rencontrez des problèmes de mémoire. Je ne vais pas entrer dans les détails, mais fondamentalement, avec SP1, nous allouons maintenant de la mémoire d’une manière beaucoup plus efficace. Fondamentalement, nous allouons 16 Mo à la fois pour les objets volumineux au lieu de 64 Mo à la fois. Nous avons tous déménagé, et nous savons tous que nous pouvons emballer beaucoup plus dans une voiture ou un camion si nous utilisons beaucoup de petites boîtes plutôt que quelques grandes boîtes. C’est l’idée ici.

N’ayez pas peur de recycler régulièrement

Nous recyclons les pools d’applications dans IIS toutes les 29 heures par défaut. Le processus Aspnet_wp.exe continue jusqu’à ce que vous terminant la tâche, redémarrez IIS ou redémarrez l’ordinateur. Ce comportement signifie que ce processus peut être en cours d’exécution pendant des mois. Il est judicieux pour certaines applications de simplement redémarrer le processus de travail tous les deux jours environ, à un moment opportun.

Questions à poser

Les précédents étaient toutes les choses que vous pouvez corriger rapidement. Toutefois, si vous rencontrez des problèmes de mémoire, posez-vous les questions suivantes :

  • Est-ce que j’utilise de nombreux objets volumineux ? Plus de 85 000 Ko sont stockés dans un tas d’objets volumineux.

  • Est-ce que je stocke des objets dans l’état Session ? Ces objets vont rester en mémoire beaucoup plus longtemps que si vous les utilisez et les éliminez.

  • Est-ce que j’utilise l’objet Cache ? Lorsqu’il est utilisé à bon escient, il s’agit d’un grand avantage pour les performances. Mais quand elle est utilisée de manière imprudente, vous vous retrouvez avec beaucoup de mémoire utilisée qui n’est jamais libérée.

  • Est-ce que je retourne recordsets trop grand pour une application web ? Personne ne veut regarder 1 000 enregistrements sur une page Web. Vous devez concevoir votre application afin de ne jamais obtenir plus de 50 à 100 enregistrements en un seul voyage.

Débogage

Je ne vais pas commencer à configurer WinDbg. Toutefois, vous pouvez utiliser les commandes suivantes pour voir ce qui se trouve exactement dans votre mémoire, si vous souhaitez résoudre des problèmes plus complexes.

!eeheap -gc

Cette commande vous indique la quantité de mémoire managée dont vous disposez. Si cette valeur est élevée, votre code managé est en cours de génération.

!dumpheap -stat

L’exécution de cette commande prend un certain temps, même des heures si votre mémoire est volumineuse. Toutefois, cette commande vous donne la liste de tous vos objets, le nombre de chaque type et la quantité de mémoire utilisée par chacun. (Par exemple, pour la StringBuilder classe , vous verrez de nombreux System.String objets)

Une fois que vous avez trouvé un objet prenant beaucoup de mémoire, explorez plus en détail à l’aide de la commande suivante :

!do <addr>

Vous pouvez obtenir l’adresse de l’objet que vous recherchez dans la dumpheap commande .

Nous allons essayer d’incorporer d’autres façons d’utiliser cet outil de diagnostic pour des situations spécifiques dans ces colonnes. Faites-nous savoir si nous faisons du bon travail !

Articles sur la mémoire et les performances

Notions de base et indicateurs de performances du garbage collector

Développement d’applications High-Performance ASP.NET

ASP.NET l’analyse des performances et quand alerter les administrateurs

Amélioration des performances et de la scalabilité des applications .NET