2010-03-18 5 views
0

J'ai créé un service Windows qui interroge en permanence une base de données. Pour ce faire, j'ai une minuterie en place. Chaque fois que j'interroge une table de base de données, j'ouvre une connexion et la ferme immédiatement après que mon travail soit terminé. En ce moment, je fais cela toutes les 20 secondes à des fins de test, mais plus tard cette fois pourrait augmenter de 5 à 10 minutes. Que se passe-t-il chaque fois que la table de base de données est interrogée, il y a une augmentation de 10-12 Ko de la taille de la mémoire du service en cours d'exécution. C'est ce que je peux voir dans le gestionnaire de tâches. Y a-t-il un moyen de contrôler cela?Comment contrôler la taille de la mémoire du service Windows en continu?

+0

Modifiez l'intervalle d'interrogation à 1 milliseconde. Vous n'aurez pas à attendre si longtemps pour voir si le garbage collector fait son travail. –

Répondre

0

La mémoire d'une application .NET est gérée par le CLR et il n'est pas recommandé de l'interférer. Je voudrais plutôt vous conseiller de profiler votre service et essayer de comprendre pourquoi il fuit la mémoire.

Que faites-vous avec les résultats de la requête? Les stockez-vous en mémoire (certains objets statiques)?

Assurez-vous d'utiliser des blocs using autour des ressources jetables telles que SqlConnection et SqlCommand.

Le garbage collector doit prendre soin de libérer des ressources.

1

Le garbage collector devrait finir par libérer et libérer de la mémoire. Ce n'est pas basé sur le temps, mais plutôt sur la pression de la mémoire. Vous devriez donc pouvoir simuler des durées plus longues en augmentant simplement la fréquence de vos interrogations. Si le GC ne récupère aucune mémoire, vous avez une fuite quelque part. N'oubliez pas non plus que les connexions à une base de données utilisent généralement le regroupement de connexions, ce qui signifie que même si la connexion est terminée, un groupe de connexions actives est toujours en attente.

Mais il est très normal de ne pas voir la mémoire récupérée instantanément. Résistez à l'envie d'utiliser GC.Collect sauf si c'est juste pour le débogage. Cela pourrait avoir une incidence sur l'efficacité du ramasse-miettes.

0

Vérifiez si vous avez une fuite de mémoire. J'utilise Windbg pour cela, comme expliqué dans CLR Memory Leak:

  • !dumpheap -stat pour voir les statistiques de chaque type
  • !dumpheap -type <LeakedTypeName> pour voir les instances du type de fuite supposée
  • !gcroot <AddressOfObject> pour suivre la référence qui épingle l'allocation (c'est-à-dire la cause de la fuite).
Questions connexes