Je suis en train d'apprendre comment C# gère la mémoire. Je suis bloqué sur les éléments statiques, j'ai lu de nombreux blogs et articles sur ce sujet, mais je ne trouve pas de réponse vraiment satisfaisante.
Définissons un bloc de code pour aider à trouver la réponse.
class myClass
{
static string myStr = "Donnée de chaîne";
static int myInt = 12;
}
Avant que vous ne partagiez votre réponse, laissez-moi partager mes découvertes que je connais sur ce sujet. N'hésitez pas à être d'accord ou en désaccord et aidez-moi à trouver la bonne réponse.
- Static est juste pour la durée de vie.
- Un type de référence statique (myStr) ira sur le tas, pour toute sa durée de vie.
- Un type de valeur statique (myInt) ira sur la pile, pour toute sa durée de vie.
Ce qui me perturbe, ce sont certaines réponses que j'ai trouvées sur internet, sur ce sujet.
Confusion numéro 1:
Lorsque votre programme démarre, il charge toutes les assemblies associées dans un AppDomain. Lorsque l'assembly est chargé, tous les constructeurs statiques sont appelés, y compris les champs statiques. Ils resteront là, et la seule façon de les décharger est de décharger l'AppDomain.
Dans les lignes ci-dessus, il est explicitement mentionné que tous les éléments statiques sont stockés dans 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, que ce soit déclaré dans un type de référence ou un type de valeur.
Si chaque variable statique est stockée sur le tas. Alors pourquoi certaines personnes disent que les variables statiques de type de valeur sont stockées sur la pile ?
S'il vous plaît, aidez-moi à relier mes points pour comprendre la gestion de mémoire des variables statiques en C#. Merci beaucoup pour votre précieux temps :)
15 votes
Les gens arrivent à se confondre énormément en traînant les concepts de "pile" et "tas" en premier lieu. Ces concepts ne sont pas utiles en soi si tout ce que vous voulez savoir est la durée de vie d'un objet ou la portée d'une déclaration, qui sont des concepts beaucoup plus pertinents en C#. La collecte des déchets signifie que, 95% du temps, tout ce dont vous avez besoin de vous soucier est de savoir si un objet est vivant ou non, et un objet référencé par un champ
static
est vivant aussi longtemps que la classe est chargée. (Quant à son instanciation, c'est un sujet plus compliqué.) Bien sûr, ceci n'est pas une réponse.1 votes
Parce qu'ils se trompent. Ils savent que les variables de type de valeur locale sont stockées sur la pile (alors que en fait toutes les variables locales sont stockées sur la pile. La confusion vient du fait que pour un type de référence, la variable est la référence, pas l'objet). Les variables statiques ressemblent à des membres de l'objet
Type
, etType
n'est pas un type de valeur. (Bien sûr, contrairement à Java, C# n'a en réalité pas de typeType
pour clarifier que chaqueType
est un type différent et a des membres différents)9 votes
@Random832: Toutes les variables locales ne sont pas sur la pile. Les variables locales fermées ne se trouvent pas sur la pile. Les variables locales dans les blocs d'itérateurs ne sont pas sur la pile. Les variables locales dans les méthodes asynchrones ne sont pas sur la pile. Les variables locales enregistrées ne sont pas sur la pile. Les variables éludées ne sont pas sur la pile. Arrêtez de croire que les variables locales vont sur la pile; c'est simplement faux. Les variables locales sont appelées locales parce que leurs noms ont une portée locale, pas parce qu'elles sont stockées sur la pile.
0 votes
@EricLippert J'ai lu votre article de blog. Votre explication est brillante sur la vérité des types de valeur. Juste une question, si un type de valeur est stocké sur le tas, il semble qu'il y ait quelques opérations de boxage et de déboxage qui se passent là-bas?
0 votes
@AliAsad: Suppose you have an array of a thousand integers. Are those integers on the stack or the heap? Are they boxed or unboxed?
0 votes
Eh bien, ce n'est pas une bonne idée de les stocker sur la pile. Il devrait être sur le tas. s'il est sur le tas alors l'enrobage se produit je suppose.
2 votes
@AliAsad: Pourquoi la boxe se produit-elle, selon vous? Qu'est-ce que c'est, la boxe de toute façon? Votre question indique que vous ne comprenez pas ce qu'est la boxe; vous pensez que "boxed" et "stored on the heap" signifient la même chose, mais ce n'est pas du tout la même chose. Il est utile pour moi de comprendre pourquoi les gens croient des choses complètement fausses à propos de C#; pourquoi pensez-vous que "boxing" signifie "on the heap"?
0 votes
@EricLippert, S'il vous plaît corrigez-moi. Merci :)
0 votes
@AliAsad: Commence par : quelle est la différence entre une variable et une valeur? Est-ce que tu comprends cette différence?
0 votes
Oui je le fais. Les variables sont des espaces réservés pour stocker des valeurs
0 votes
@AliAsad: Les variables sont des emplacements de stockage qui stockent des valeurs, oui. Considérez quatre types de variables utilisées dans une méthode : les formelles, les locales, les champs d'une classe et les éléments d'un tableau.
T M(T formelle) { T locale = new T(); local.champ = new[] { formelle }; return locale; }
T est un type de classe. Quelles sont les durées de vie de chacune des quatre variables par rapport à l'activation de M?