J'ai écrit du C ++ pendant 10 ans. J'ai rencontré des problèmes de mémoire, mais ils pourraient être résolus avec un effort raisonnable.
Depuis quelques années, j'écris en C #. Je trouve que j'ai encore beaucoup de problèmes de mémoire. Ils sont difficiles à diagnostiquer et à corriger en raison de la non-détermination, et parce que la philosophie C # est que vous ne devriez pas avoir à vous soucier de telles choses lorsque vous le faites très certainement.
Un problème particulier que je trouve est que je dois explicitement éliminer et nettoyer tout dans le code. Si je ne le fais pas, alors les profileurs de mémoire n'aident pas vraiment car il y a tellement de paillettes qui flottent que vous ne pouvez pas trouver de fuite dans toutes les données qu'ils essaient de vous montrer. Je me demande si j'ai une mauvaise idée ou si l'outil que j'ai n'est pas le meilleur.
Quels types de stratégies et d'outils sont utiles pour lutter contre les fuites de mémoire dans .NET?
la source
Réponses:
J'utilise MemProfiler de Scitech lorsque je soupçonne une fuite de mémoire.
Jusqu'à présent, je l'ai trouvé très fiable et puissant. Cela a sauvé mon bacon au moins une fois.
Le GC fonctionne très bien dans .NET IMO, mais comme tout autre langage ou plate-forme, si vous écrivez du mauvais code, de mauvaises choses se produisent.
la source
Juste pour le problème de l'oubli de se débarrasser, essayez la solution décrite dans cet article de blog . Voici l'essence:
la source
Nous avons utilisé le logiciel Ants Profiler Pro by Red Gate dans notre projet. Cela fonctionne très bien pour toutes les applications basées sur le langage .NET.
Nous avons constaté que le garbage collector .NET est très «sûr» dans son nettoyage des objets en mémoire (comme il se doit). Il garderait des objets à portée de main juste parce que nous pourrions l'utiliser dans le futur. Cela signifiait que nous devions être plus prudents sur le nombre d'objets que nous gonflions en mémoire. En fin de compte, nous avons converti tous nos objets de données en un «gonflement à la demande» (juste avant qu'un champ ne soit demandé) afin de réduire la surcharge mémoire et d'augmenter les performances.
EDIT: Voici une explication supplémentaire de ce que j'entends par «gonfler à la demande». Dans notre modèle d'objet de notre base de données, nous utilisons les propriétés d'un objet parent pour exposer le ou les objets enfants. Par exemple, si nous avions un enregistrement qui faisait référence à un autre enregistrement "détaillé" ou "recherche" sur une base individuelle, nous le structurerions comme ceci:
Nous avons constaté que le système ci-dessus créait de réels problèmes de mémoire et de performances lorsqu'il y avait beaucoup d'enregistrements en mémoire. Nous sommes donc passés à un système où les objets n'étaient gonflés que lorsqu'ils étaient demandés, et les appels à la base de données n'étaient effectués que lorsque cela était nécessaire:
Cela s'est avéré beaucoup plus efficace car les objets étaient conservés hors de la mémoire jusqu'à ce qu'ils soient nécessaires (la méthode Get a été accédée). Il a fourni une très grande amélioration des performances en limitant les accès à la base de données et un énorme gain d'espace mémoire.
la source
Vous devez toujours vous soucier de la mémoire lorsque vous écrivez du code managé, sauf si votre application est triviale. Je vais suggérer deux choses: tout d'abord, lisez CLR via C # car cela vous aidera à comprendre la gestion de la mémoire dans .NET. Deuxièmement, apprenez à utiliser un outil comme CLRProfiler (Microsoft). Cela peut vous donner une idée de la cause de votre fuite de mémoire (par exemple, vous pouvez jeter un œil à la fragmentation de votre tas d'objets volumineux)
la source
Utilisez-vous du code non géré? Si vous n'utilisez pas de code non géré, selon Microsoft, les fuites de mémoire au sens traditionnel du terme ne sont pas possibles.
Cependant, la mémoire utilisée par une application peut ne pas être libérée, de sorte que l'allocation de mémoire d'une application peut augmenter tout au long de la vie de l'application.
Pour traiter ce type de problème, vous pouvez implémenter IDisposable . Si vous voulez voir certaines des stratégies pour gérer la gestion de la mémoire, je suggérerais de rechercher IDisposable, XNA, la gestion de la mémoire, car les développeurs de jeux ont besoin d'un ramassage des ordures plus prévisible et doivent donc forcer le GC à faire son travail.
Une erreur courante consiste à ne pas supprimer les gestionnaires d'événements qui s'abonnent à un objet. Un abonnement à un gestionnaire d'événements empêchera un objet d'être recyclé. Jetez également un œil à l' instruction using qui vous permet de créer une portée limitée pour la durée de vie d'une ressource.
la source
Ce blog propose de très belles procédures pas à pas utilisant windbg et d'autres outils pour détecter les fuites de mémoire de tous types. Excellente lecture pour développer vos compétences.
la source
Je viens d'avoir une fuite de mémoire dans un service Windows, que j'ai corrigé.
Tout d'abord, j'ai essayé MemProfiler . Je l'ai trouvé très difficile à utiliser et pas du tout convivial.
Ensuite, j'ai utilisé JustTrace qui est plus facile à utiliser et vous donne plus de détails sur les objets qui ne sont pas supprimés correctement.
Cela m'a permis de résoudre très facilement la fuite de mémoire.
la source
Si les fuites que vous observez sont dues à une implémentation de cache emballante, il s'agit d'un scénario dans lequel vous voudrez peut -être envisager l'utilisation de WeakReference. Cela pourrait aider à garantir que la mémoire est libérée si nécessaire.
Cependant, à mon humble avis, il serait préférable d'envisager une solution sur mesure - vous seul savez vraiment combien de temps vous avez besoin pour conserver les objets, donc la conception d'un code de gestion interne approprié à votre situation est généralement la meilleure approche.
la source
Je préfère dotmemory de Jetbrains
la source
Big guns - Outils de débogage pour Windows
Ceci est une incroyable collection d'outils. Vous pouvez analyser les tas gérés et non gérés avec lui et vous pouvez le faire hors ligne. C'était très pratique pour déboguer l'une de nos applications ASP.NET qui continuait à recycler en raison d'une utilisation excessive de la mémoire. Je n'avais qu'à créer un vidage mémoire complet du processus vivant en cours d'exécution sur le serveur de production, toutes les analyses ont été effectuées hors ligne dans WinDbg. (Il s'est avéré que certains développeurs utilisaient excessivement le stockage de session en mémoire.)
"Si cassé c'est ..." le blog contient des articles très utiles sur le sujet.
la source
La meilleure chose à garder à l'esprit est de garder une trace des références à vos objets. Il est très facile de se retrouver avec des références suspendues à des objets dont vous ne vous souciez plus. Si vous n'utilisez plus quelque chose, débarrassez-vous-en.
Habituez-vous à utiliser un fournisseur de cache avec des expirations glissantes, de sorte que si quelque chose n'est pas référencé pour une fenêtre de temps souhaitée, il soit déréférencé et nettoyé. Mais si on y accède beaucoup, cela le dira en mémoire.
la source
L'un des meilleurs outils consiste à utiliser les outils de débogage pour Windows et à effectuer un vidage de la mémoire du processus à l'aide d' adplus , puis à utiliser windbg et le plugin sos pour analyser la mémoire du processus, les threads et les piles d'appels.
Vous pouvez également utiliser cette méthode pour identifier les problèmes sur les serveurs, après avoir installé les outils, partagez le répertoire, puis connectez-vous au partage à partir du serveur en utilisant (net use) et effectuez un crash ou un hang dump du processus.
Ensuite, analysez hors ligne.
la source
Après l'un de mes correctifs pour une application gérée, j'ai eu la même chose, comme comment vérifier que mon application n'aura pas la même fuite de mémoire après ma prochaine modification, j'ai donc écrit quelque chose comme le cadre de vérification de la libération des objets, veuillez jeter un œil sur le package NuGet ObjectReleaseVerification . Vous pouvez trouver un exemple ici https://github.com/outcoldman/OutcoldSolutions-ObjectReleaseVerification-Sample , et des informations sur cet exemple http://outcoldman.ru/en/blog/show/322
la source
À partir de Visual Studio 2015, envisagez d'utiliser l' outil de diagnostic d'utilisation de la mémoire prêt à l'emploi pour collecter et analyser les données d'utilisation de la mémoire.
L'outil Utilisation de la mémoire vous permet de prendre un ou plusieurs instantanés du tas de mémoire géré et natif pour vous aider à comprendre l'impact sur l'utilisation de la mémoire des types d'objet.
la source
l'un des meilleurs outils que j'ai utilisé son DotMemory.vous pouvez utiliser cet outil comme une extension dans VS.après avoir exécuté votre application, vous pouvez analyser chaque partie de la mémoire (par objet, espace de nom, etc.) que votre application utilise et en prendre un instantané , Comparez-le avec d'autres SnapShots. DotMemory
la source