Des memory leaks sont-elles possibles dans des environnements gérés tels que .NET?

En C ++, il est facilement possible d’avoir une fuite de mémoire permanente – allouez simplement la mémoire sans la libérer

new char; //permanent memory leak guaranteed 

et que la mémoire rest allouée pendant la durée de vie du segment de mémoire (généralement identique à la durée d’exécution du programme).

Est-ce que le même (un cas qui mènera à un object spécifique non référencé n’a jamais été publié alors que les mécanismes de gestion de mémoire fonctionnent correctement) est possible dans un programme C #?

J’ai lu attentivement cette question et ses réponses, qui mentionnent des cas qui entraînent une consommation de mémoire supérieure à celle attendue ou des cas extrêmes comme un blocage du thread du finaliseur, mais une fuite permanente peut se former dans un programme C # fonctionnant normalement. gestion de la mémoire?

Cela dépend de la manière dont vous définissez une fuite de mémoire. Dans une langue non gérée, nous pensons généralement qu’une fuite de mémoire est une situation dans laquelle la mémoire a été allouée et qu’il n’y a aucune référence à celle-ci. Nous ne pouvons donc pas la libérer.

Ce type de fuite est quasiment impossible à créer dans .NET (sauf si vous appelez du code non géré ou s’il y a un bogue dans le moteur d’exécution).

Cependant, vous pouvez obtenir une autre forme de fuite “plus faible”: lorsqu’une référence à la mémoire existe (il est donc toujours possible de trouver et de réinitialiser la référence, ce qui permet au CPG de libérer la mémoire normalement), mais vous pensiez qu’elle ne l’était pas. t, vous avez donc supposé que l’object référencé serait traité par GC. Cela peut facilement conduire à une croissance sans limite de la consommation de mémoire, car vous accumulez des références à des objects qui ne sont plus utilisés, mais qui ne peuvent pas être récupérés, car ils sont toujours référencés quelque part dans votre application.

Ainsi, ce qui est généralement considéré comme une fuite de mémoire dans .NET est simplement une situation dans laquelle vous avez oublié que vous avez une référence à un object (par exemple, parce que vous n’avez pas réussi à vous désabonner d’un événement). Mais la référence existe et si vous vous en souvenez, vous pouvez la supprimer et la fuite disparaîtra.

Vous pouvez écrire du code non managé dans .NET si vous le souhaitez. Vous avez inclus votre bloc de code avec un mot clé non sécurisé. Par conséquent, si vous écrivez un code non sécurisé, ne revenez-vous pas au problème de la gestion de la mémoire et si ce n’est une fuite de mémoire?

Ce n’est pas exactement une fuite de mémoire, mais si vous communiquez directement avec les pilotes de matériel (c’est-à-dire pas via une extension .net correctement écrite d’un ensemble de pilotes), il est assez possible de placer le matériel dans un état où, bien ou peut ne pas être une fuite de mémoire réelle dans votre code, vous ne pouvez plus accéder au matériel sans le redémarrer ou le PC …

Pas sûr que ce soit une réponse utile à votre question, mais j’ai pensé que cela valait la peine d’être mentionné.

GC retarde généralement la collecte de la mémoire inaccessible à une date ultérieure lorsqu’une parsing des références montre que la mémoire est inaccessible. (Dans certains cas, le compilateur peut aider le CPG et l’avertir qu’une zone mémoire est inaccessible lorsqu’elle le devient.)

En fonction de l’algorithme du GC, la mémoire inaccessible est détectée dès qu’un cycle de collecte est exécuté ou peut restr non détectée pendant un certain nombre de cycles de collecte (les générations GC montrent ce comportement, par exemple). Certaines techniques ont même des angles morts qui ne sont jamais collectés (utilisation d’un pointeur compté de références, par exemple). Certaines leur refusent le nom d’algorithme GC. Elles sont probablement inappropriées dans un contexte général.

Prouver qu’une zone spécifique sera récupérée dépendra de l’algorithme et du modèle d’allocation de mémoire. Pour un algorithme simple tel que mark et sweep, il est facile de donner une borne (dit jusqu’au cycle de collecte suivant), pour des algorithmes plus complexes, la matière est plus complexe (sous un schéma utilisant un nombre dynamic de générations, les conditions dans lesquelles une la collection complète est terminée ne sont pas significatives pour quelqu’un qui n’est pas familiarisé avec les détails de l’algorithme et avec les méthodes heuristiques précises utilisées)

Une réponse simple est que les memory leaks classiques sont impossibles dans les environnements CPG, car classiquement une fuite de mémoire est une fuite car, en tant que bloc non référencé, il n’ya aucun moyen pour le logiciel de le trouver pour le nettoyer.

D’autre part, une fuite de mémoire est une situation dans laquelle l’utilisation de la mémoire d’un programme a une croissance sans limite. Cette définition est utile pour parsingr le risque d’échec d’un logiciel lorsqu’il est exécuté en tant que service (lorsque des services sont censés être exécutés, peut-être pendant des mois).

En tant que telle, toute structure de données évolutive qui continue à conserver des références à des objects inutiles peut entraîner une défaillance effective du logiciel de service en raison de l’épuisement de l’espace d’adressage.

Plus facile fuite de mémoire:

 public static class StaticStuff { public static event Action SomeStaticEvent; } public class Listener { public Listener() { StaticStuff.SomeStaticEvent+=DoSomething; } void DoSomething() {} } 

les instances de Listener ne seront jamais collectées.

Si nous définissons une fuite de mémoire comme une condition dans laquelle une mémoire pouvant être utilisée pour créer des objects ne peut pas être utilisée ou une mémoire pouvant être libérée ne l’est pas

Les memory leaks peuvent se produire dans:

  • Evénements dans WPF où des événements faibles doivent être utilisés. Cela peut surtout arriver dans les propriétés attachées .
  • Gros objects

Fragmentation du tas de gros objects

http://msdn.microsoft.com/en-us/magazine/cc534993.aspx