Le GC peut déplacer des références autour; l'utilisation non sécuritaire tient un objet à l'extérieur de la table de contrôle, et permet d'éviter cela. "Fixe" les broches d'un objet, mais laisse le GC gérer la mémoire.
Par définition, si vous avez un pointeur vers l'adresse d'un objet, et la GC qui bouge, le pointeur de la souris n'est plus valide.
Pourquoi vous avez besoin de pointeurs: raison Principale est de travailler avec Dll non gérées, par exemple, ceux écrits en C++
A noter aussi, lorsque vous épinglez des variables et utiliser les pointeurs, vous êtes plus sensible à la fragmentation du segment.
Modifier
Vous avez abordé la question au cœur de tablespaces gérés de code non managé... comment la mémoire se libère?
Vous pouvez mélanger du code de la performance que vous décrivez, vous ne pouvez pas traverser réussi/non géré limites avec des pointeurs (c'est à dire que vous ne pouvez pas utiliser les pointeurs à l'extérieur de la "dangereux" contexte).
Comme pour la façon dont ils sont nettoyées... à Vous de gérer votre propre mémoire; les objets que votre pointeurs point à été créé/alloué (en général, dans la DLL C++) à l'aide de (espérons-le) CoTaskMemAlloc()
, et vous devez libérer de la mémoire, de la même manière, en appelant CoTaskMemFree()
, ou vous allez avoir une fuite de mémoire. Notez que seule la mémoire allouée avec CoTaskMemAlloc()
peut être libéré avec CoTaskMemFree()
.
L'autre alternative est d'exposer une méthode à partir de votre natif C++ dll qui prend un pointeur et la libère... ce qui permet à la DLL décider comment libérer de la mémoire, ce qui fonctionne le mieux si elle a utilisé une autre méthode pour allouer de la mémoire. La plupart des dll natives vous travaillez avec dll de tiers que vous ne pouvez pas modifier, et ils n'ont généralement pas (que j'ai vu) de telles fonctions à appeler.
Un exemple de libérer de la mémoire, prises à partir d' ici:
string[] array = new string[2];
array[0] = "hello";
array[1] = "world";
IntPtr ptr = test(array);
string result = Marshal.PtrToStringAuto(ptr);
Marshal.FreeCoTaskMem(ptr);
System.Console.WriteLine(result);
Certains plus du matériel de lecture:
C# désalloue la mémoire référencée par IntPtr
La deuxième réponse en bas de explique la différence d'allocation/désallocation de méthodes
Comment gratuit IntPtr en C#?
Renforce la nécessité de libérer de la même manière, la mémoire a été allouée
http://msdn.microsoft.com/en-us/library/aa366533%28VS.85%29.aspx
Officiel de la documentation MSDN sur les différentes manières d'allouer et de libérer de la mémoire.
Bref... vous avez besoin de savoir comment la mémoire a été allouée pour la libérer.
Modifier
Si je comprends votre question correctement, la réponse courte est oui, vous pouvez à la main les données non gérées pointeurs, travailler avec elle dans un contexte dangereux, et les données disponibles une fois que vous quittez le contexte dangereux.
La clé est que vous avez à la broche de l'objet géré, vous faites référence à un fixed
bloc. Cela empêche la mémoire, vous faites référence à d'être déplacé par le GC alors que dans l' unsafe
bloc. Il y a un certain nombre de subtilités en cause ici, par exemple, vous ne pouvez pas réaffecter un pointeur initialisé dans un bloc fixe... vous devriez lire sur dangereux et fixe des instructions si vous êtes vraiment à la gestion de votre propre code.
Tout ce que dit, les avantages de la gestion de vos propres objets et en utilisant des pointeurs de la manière que vous décrivez ne peut pas vous acheter autant d'une augmentation de la performance que vous pourriez le penser. Raisons de ne pas:
- C# est très optimisé et très rapide
- Votre pointeur de code est généré comme IL, qui doit être jitted (à quel point des optimisations supplémentaires entrent en jeu)
- Vous n'êtes pas en tournant le Garbage Collector hors... vous êtes juste de garder les objets que vous travaillez avec de la GC de sa juridiction. Ainsi, chaque 100ms, le GC encore interrompt votre code et exécute ses fonctions pour toutes les autres variables dans votre code géré.
HTH,
James