J'essaie d'apprendre comment C # gère la mémoire. Je suis coincé sur des éléments statiques, j'ai lu de nombreux blogs et articles sur ce sujet, mais je ne trouve pas de réponse tout à fait satisfaisante.
Définissons un bloc de code pour aider à trouver la réponse.
class myClass
{
static string myStr = "String Data";
static int myInt = 12;
}
Avant de partager votre réponse, permettez-moi de partager mes conclusions que je connais à ce sujet. N'hésitez pas à être d'accord ou en désaccord et aidez-moi à trouver la bonne réponse.
Ce qui m'embrouille, ce sont quelques réponses que j'ai trouvées sur internet, à ce sujet.
Confusion numéro 1:
Lorsque votre programme démarre, il charge tous les assemblys associés dans un AppDomain. Lorsque l'assembly est chargé, tous les constructeurs statiques sont appelés, y compris les champs statiques. Ils vivront là-bas et la seule façon de les décharger est de décharger l'AppDomain.
Dans les lignes ci-dessus, il est mentionné explicitement que tous les éléments statiques stockés sur AppDomain. Alors pourquoi tout le monde sur Internet dit que les éléments "statiques" sont stockés sur le tas/la pile?
Confusion numéro 2:
Chaque variable statique est stockée sur le tas, qu'elle soit déclarée dans un type de référence ou un type de valeur.
Si chaque variable statique stockée sur le tas. Alors pourquoi certains disent que les variables statiques de type valeur sont stockées sur la pile?
Aidez-moi à connecter mes points pour comprendre la gestion de la mémoire des variables statiques en C #. Merci beaucoup pour votre précieux temps :)
Tout d'abord, notez que tout cela est un détail d'implémentation. La seule chose que le runtime garantit est:
C'est à peu près ça. Tout le reste est un détail d'implémentation - la spécification ne se soucie pas de la pile, du tas ou de toute autre chose. Cela dépend de l'implémentation du runtime, et un runtime valide pourrait tout mettre sur la pile, s'il le souhaite, ou sur le tas. Et n'oubliez pas les registres.
Voyons maintenant certaines des idées fausses que vous avez déjà réussi à capter:
TypeLoadException
, très probablement dans une méthode qui fait d'abord référence au type (inutile de dire que cela peut rendre le débogage des statistiques délicates).Certaines personnes peuvent être confuses. Certains ne comprennent pas la différence entre le contrat et les implémentations pratiques. Certains ne savent tout simplement pas de quoi ils parlent. J'aimerais qu'il y ait un moyen facile de savoir lequel est lequel, mais il n'y en a pas. En cas de doute, vous pouvez consulter les spécifications C #/CLR, mais cela ne vous renseigne que sur le contrat, pas sur la réalité pratique.
L'intérêt de la mémoire gérée est que vous n'êtes pas censé vous soucier de ces détails d'implémentation. Bien sûr, comme toute abstraction, elle fuit - et il est logique de savoir comment les choses se passent réellement, jusqu'aux micro-instructions du processeur, à la mise en cache de la mémoire, etc., à travers toutes les différentes couches et abstractions. Mais il n'y a rien à sur lequel s'appuyer - l'implémentation peut changer à tout moment, et cela s'est produit à plusieurs reprises dans le passé.
Chaque fois qu'un processus est chargé dans la RAM, nous pouvons dire que la mémoire est grossièrement divisée en trois zones (dans ce processus): Stack, Heap et Static (qui, en .NET, est en fait une zone spéciale à l'intérieur de Heap uniquement connue sous le nom de Tas à haute fréquence).
La partie statique contient les variables et méthodes membres "statiques". Qu'est-ce qui est exactement statique? Les méthodes et variables qui ne nécessitent pas la création d'une instance d'une classe sont définies comme étant statiques
En savoir plus ici .
Il existe une instance de la classe créée, avec tous les membres statiques initialisés.
Les membres des classes statiques sont normalement stockés sur le tas, les membres des types valeur sont normalement stockés sur la pile.
Cela ne doit pas être le cas, vous pouvez lire this blog pour plus d'informations.
Il s'agit d'un des concepteurs de langage de C #, Eric Lippert.
Le blog montre que contrairement aux connaissances normales, il n'est pas sûr que les types de valeur se trouvent sur la pile et que les types de référence soient sur le tas, mais ils le sont généralement.
Ce n'est tout simplement pas spécifié dans la spécification.