2010-10-26 8 views
3

Les performances de ma application se détériorent à mesure qu'elle continue de durer toute la journée.C# Diminution de la performance de l'application due à la collecte des ordures?

Je suppose que c'est un garbage collector, comment puis-je vérifier cela? Existe-t-il un moyen de savoir quel objet/fonction est à l'origine de la surcharge de la récupération de place?

Existe-t-il un moyen d'effectuer manuellement la collecte de place par programme pour effacer la mémoire des fuites?

Merci,

modifier À une extrémité de l'application, il reçoit un rappel d'un api non géré pour accepter les données, les processus, puis d'envoyer des messages de prise sur la seconde extrémité. À partir de la seconde extrémité, il récupère ensuite les données de suivi sur les messages qu'il a envoyés. L'application ouvre 5-6 sockets pour envoyer et recevoir des données à partir de la seconde extrémité. Il enregistre constamment beaucoup de données dans le système de fichiers Windows sur un thread séparé. Mes mesures incluent l'horodatage (compteur de queryperformance) juste avant d'envoyer des données et l'horodatage à nouveau lorsque je reçois le suivi d'un autre processus sur le socket. J'ai remarqué que sur plusieurs sockets que j'ouvre, la détérioration des performances se produit sur une seule connexion socket.

Le traitement entre les données d'horodatage et d'envoi de données sur le socket inclut l'itération à travers 2 arraylist qui n'a pas plus de 5-6 objets et quelques rappels.

L'utilisation de la mémoire à partir de la fenêtre Task MAnager ne monte pas considérablement. De 96 Mo à 100 Mo après 6-7 heures de fonctionnement.

Ci-dessous sont quelques observations de l'exécution de perfmon.

« survivants de finanlization » et « mémoire finalisation promu de Gen 0 » augmenter progressivement avec le temps

« Gen 0 collections » allant de 1819 au début de 6000 au bout de 4 heures. "Collections Gen 1" représente 10% -12% de la collection Gen 0 et "Collection Gen 2" 1% ou moins. Considérant que les numéros de collection Gen 0 sont cumulatifs, ce n'est probablement pas une préoccupation majeure.

poignées GC » ont augmenté de 850ish à 4000.

+1

duplication possible de [en utilisant perfmon pour détecter la détérioration des performances] (http://stackoverflow.com/questions/3991681/using-perfmon-to-detect-performance-detioration) –

Répondre

4

Il est beaucoup plus probable que vous avez une fuite de mémoire, et en invoquant le GC ne sera pas utile manuellement que: il ne peut pas disposer des objets si votre code hasn « t les a libérés.

Modifier

Puisque vos poignées de GC augmentent, this page suggère qu'il existe des ressources non gérés qui ne reçoivent pas libérés. J'ai eu cela arrive avec des bitmaps, par exemple, mais vous devrez peut-être nous en dire beaucoup plus sur votre applica tion pour obtenir une suggestion plus spécifique.

Here's a thread qui peut vous donner un aperçu utile.

+0

Vais-je voir "l'utilisation de la mémoire" augmenter la fenêtre "Task Manager" pour le processus s'il y a une fuite de mémoire? – bsobaid

+0

Oui, s'il y en a assez pour vous en soucier. – egrunin

+0

donc l'utilisation de la mémoire est passée seulement de 96 Mo à 100 Mo. – bsobaid

4

Vous pouvez appeler le GC.Collect() pour forcer la récupération de place, mais cela ne corrigera pas les fuites de mémoire. Essayez un profileur de mémoire comme profileur de mémoire ANTS pour trouver des fuites de mémoire.

ANTS memory profiler

+3

Généralement appeler 'GC.Collect()' est une mauvaise idée, car le garbage collector fait généralement un meilleur travail que vous (ou le développeur) peut faire – PostMan

+0

Pour certains besoins spécialisés, cependant, comme les serveurs COM indépendants, c'est la seule façon pour régir la vie de référence car elle doit être gouvernée. –

+0

De même, si vous placez beaucoup de choses temporaires en mémoire pour effectuer des actions sur celles-ci, alors en mémorisant les résultats, appeler GC.Collect() 'aidera si les boucles sont assez rapides. J'ai eu des problèmes de MOO parce que GC ne se passait pas assez rapidement, mais j'ai dû faire des profils pour savoir que cela m'aiderait vraiment. – KallDrexx

2

Il peut ne pas être nécessairement un problème de mémoire. Utilisez Windows Performance Monitor (voir dans les outils d'administration) pour surveiller le processeur, la mémoire, le nombre d'objets GDI, le nombre de handles de votre application et voir si l'un d'entre eux semble grimper pendant la durée de vie de votre application.

Souvent, vous constaterez que vous utilisez quelque chose de System.Drawing et n'appelez pas Dispose() dessus, provoquant une fuite de handle. J'ai constaté que les fuites de la poignée ont tendance à manger beaucoup plus vite que les fuites de mémoire. Et les fuites de poignée ne causent aucune pression de GC, signifiant que vous pourriez avoir des poignées de fuite comme un tamis et le GC ne connaîtrait jamais la différence.

Donc, longue histoire courte: mesurer, mesurer, mesurer. Ensuite, vous saurez quoi réparer.

+0

+1 sur les fuites de l'espace de noms system.drawing. – JoshRoss

+0

l'ajout de compteurs dans perfmon entraîne-t-il des pertes de performances? – bsobaid

+0

@bsobaid: Douteuse que cela causerait des frais généraux appréciables. Vous souffrez déjà de problèmes de performance, vous pourriez aussi bien passer une journée à mesurer la source du problème. – FMM