web-dev-qa-db-fra.com

Quels sont les objets épinglés?

J'essaie de trouver une fuite de mémoire en utilisant le profileur de mémoire des fourmis, et j'ai rencontré dans un nouveau terme:

Objets épinglés.

Quelqu'un peut-il me donner une bonne et simple explication sur ce que sont ces objets, comment puis-je épingler/débloquer des objets et détecter qui a épinglé des objets?

Merci

46
sagie

Un objet épinglé n'est pas autorisé à se déplacer. Le garbage collector compacte normalement la mémoire en ce qu'il déplace tous les objets vers "un ou plusieurs clusters". Il s'agit de créer de gros morceaux d'espace libre.

Cela signifie essentiellement que si quelqu'un d'autre (extérieur) a un pointeur vers l'adresse mémoire d'un objet, cela peut pointer vers un contenu aléatoire - car l'objet a bougé.

L'épinglage d'un objet indique au GC de NE PAS LE DÉPLACER. Ceci est normalement inutile et n'a de sens que lorsque vous travaillez avec des pointeurs - comme lorsque vous utilisez PInvoke. Parfois, vous devez rendre une adresse à une structure (dans le terme de disposition de mémoire), et si cela est implémenté dans une classe, vous devez l'épingler.

Pour répondre concrètement:

  • Vous ne pouvez pas savoir qui a épinglé un objet.
  • L'épinglage se fait avec l'instruction FIXED. Ceci n'est autorisé que dans un code dangereux.

Vérifier:

http://msdn.Microsoft.com/en-us/library/f58wzh21%28VS.80%29.aspx

52
TomTom

Un objet épinglé est un objet qui ne peut pas être déplacé par le garbage collector, ce qui signifie que son adresse doit être conservée car quelqu'un d'autre, généralement un morceau de code non géré, dépend du fait que l'objet se trouve à une adresse mémoire définie.

Habituellement, le garbage collector a la liberté de déplacer des objets en mémoire. Dans le code managé, comme le garbage collector a la possibilité d'accéder à toutes les références, il peut remapper librement un objet vers un emplacement différent, puis mettre à jour toutes les références à cet objet afin que le processus soit transparent pour le code en cours d'exécution. De cette façon, le GC a la capacité de mieux organiser la mémoire du programme et de la compacter si nécessaire.

Lorsqu'un objet non géré interagit avec votre code (dans des sections non sécurisées), une situation peut se produire où il y a un pointeur quelque part vers un morceau de votre code - par exemple, vers un morceau de mémoire adressé dans votre code qui est géré par un appel COM externe. Cette mémoire ne peut pas être remappée car l'appel COM s'attend à ce que l'objet se trouve dans une adresse donnée et donc, s'il a été déplacé, le GC n'aurait aucun moyen de notifier l'objet COM de cette modification, ce qui entraînerait un accès violation ou pire.

19
Jorge Córdoba

Les objets épinglés sont utilisés lors de la communication avec du code non géré. Dans le code managé, le garbage collector est libre de déplacer les blocs de mémoire, car il connaît toutes les références au bloc de mémoire et peut les mettre à jour en conséquence.

Lors de la communication avec du code non géré (par exemple Win-API), les pointeurs vers les données ou les tampons sont souvent passés en argument. Si le garbage collector était libre de déplacer ces données, les pointeurs deviendraient soudainement invalides. Comme le pointeur est transféré vers du code non géré, il n'est pas possible pour le GC de mettre à jour le pointeur - ni même de savoir où il est utilisé. Pour empêcher le déplacement de la mémoire et vous assurer que les données restent à l'endroit connu du pointeur du code non géré, l'objet peut être épinglé.

6
Anders Abel

La raison pour laquelle vous pourriez épingler un objet est si vous effectuez des appels à du code non managé.

Lorsque le garbage collector s'exécute, il peut supprimer un objet qui n'est plus nécessaire. Cela laisse un "trou" d'espace libre dans le tas. Le GC compacte ensuite le tas en déplaçant les objets restants ensemble pour vous assurer que l'espace libre est dans un bloc continu (un peu comme défragmenter votre disque dur).

Il met également à jour toutes les références (dans le code managé) à tous les objets qui ont été déplacés dans le cadre du compactage.

Si vous travaillez avec du code non managé (par exemple du C++ externe) et lui donnez un pointeur vers un objet, il n'y a aucun moyen pour le GC de dire au code non managé que l'objet a bougé après son exécution. Par conséquent, vous pouvez marquer l'objet que vous partagez avec le code externe comme épinglé afin de ne pas avoir le problème du pointeur non valide.

6
Paolo

Pour épingler des objets, vous pouvez utiliser le mot-clé fixed :

L'instruction fixed empêche le garbage collector de déplacer une variable mobile. L'instruction fixe n'est autorisée que dans un contexte dangereux.

Un exemple que j'ai vu auparavant est de diviser une longue valeur en octets afin qu'elle puisse être encodée en une clé série. Cela a été fait dans un contexte nsafe afin d'obtenir le pointeur. Des erreurs intermittentes ont commencé à se produire car la récupération de place se produirait à mi-chemin du processus d'obtention des octets individuels. La valeur serait déplacée et nous nous sommes retrouvés avec la moitié des octets corrects, la moitié des octets de déchets.

La solution pour nous était d'utiliser la classe BitConverter . Si vous regardez le code sous-jacent de la classe BitConverter, vous verrez qu'il utilise le mot-clé fixe pour épingler le tableau d'octets tout en obtenant les octets de la variable.

5
Richard Nienaber

Un objet épinglé est un objet qui a un emplacement défini en mémoire.

Normalement, le garbage collector compacte le tas géré, ce qui modifie l'emplacement des objets en mémoire. Si vous avez du code non managé qui se réfère à un objet C # que vous avez créé, vous voudrez peut-être faire référence à l'emplacement de mémoire absolument. L'épinglage de l'objet vous permet de le faire avec certitude.

Vous pouvez les créer à l'aide de l'instruction fixed: http://msdn.Microsoft.com/en-us/library/f58wzh21%28VS.80%29.aspx

4
JonC

obtenu à partir de msdn "Un objet épinglé est un objet que le garbage collector ne peut pas déplacer en mémoire"

http://msdn.Microsoft.com/en-us/library/x2tyfybc (VS.71) .aspx

2
CliffC