C# Language Objet épinglé


Exemple

GC (Garbage Collector) est responsable du nettoyage de nos déchets.

Alors que GC nettoie nos déchets, il supprime les objets inutilisés du tas géré, ce qui provoque une fragmentation du tas. Lorsque le GC est terminé avec la suppression, il effectue une compression de tas (défragmintation) qui consiste à déplacer des objets sur le tas.

Comme GC n'est pas déterministe, lors du passage d'une référence / d'un pointeur d'objet géré à un code natif, GC peut intervenir à tout moment, s'il survient juste après l'appel Inerop. être déplacé sur le tas géré - par conséquent, nous obtenons une référence non valide du côté géré.

Dans ce scénario, vous devez épingler l'objet avant de le transmettre au code natif.

Objet épinglé

L'objet épinglé est un objet qui n'est pas autorisé à se déplacer par GC.

Poignée épinglée Gc

Vous pouvez créer un objet pin en utilisant la méthode Gc.Alloc

GCHandle handle = GCHandle.Alloc(yourObject, GCHandleType.Pinned); 
  • L'obtention d'un objet GCHandle épinglé à un objet géré marque un objet spécifique comme un objet qui ne peut pas être déplacé par GC , jusqu'à ce que la poignée soit libérée.

Exemple:

[DllImport("kernel32.dll", SetLastError = true)]
public static extern void EnterCriticalSection(IntPtr ptr);

[DllImport("kernel32.dll", SetLastError = true)]
public static extern void LeaveCriticalSection(IntPtr ptr);
       
public void EnterCriticalSection(CRITICAL_SECTION section)
{
    try
    {
        GCHandle handle = GCHandle.Alloc(section, GCHandleType.Pinned); 
        EnterCriticalSection(handle.AddrOfPinnedObject());
        //Do Some Critical Work
        LeaveCriticalSection(handle.AddrOfPinnedObject());
    }
    finaly
    {
        handle.Free()
    }
}

Précautions

  • Lorsque vous épinglez (surtout les plus gros), l'objet essaye de libérer le GcHandle épinglé aussi rapidement que possible, car il interrompt la défragmentation du tas.
  • Si vous oubliez de libérer GcHandle, rien ne se passera. Faites-le dans une section de code sécurisée (telle que finaly)