2017-07-25 1 views
-1

Je lisais sur le motif Dispose et je vois comment le memory is allocated. Voici la citation de http://codebetter.com/karlseguin/2008/04/28/foundations-of-programming-pt-7-back-to-basics-memory/.Quelle est l'importance majeure/rôle de la mémoire de pile si la plupart des données vont sur tas?

allocation mémoire
....
....
La seule exception à cette règle sont les types de valeurs appartenant à des types de référence - par exemple la propriété Id d'une classe utilisateur va sur la tas avec l'instance de la classe User elle-même.

Ceci est également mentionné à la question sur Stack Overflow ici. D'après ce que j'ai compris, tous les types de valeur, quel que soit l'endroit où ils sont déclarés, vont à la pile. Cela semble faux maintenant. Dans le code ci-dessous, i ira sur tas; PAS sur la pile selon les liens. C'est parce que MyClass est le type de référence qui ira à tas et avec lui, tous ses types de valeur. Ok, donc seuls les types de valeurs qui ne font pas partie de la classe vont dans la mémoire de la pile. Droite? Mais, presque tout dans le langage Dot Net comme C# est en classe. Alors qu'est-ce qui va exactement à la mémoire de la pile? Ce answer explique les types de valeur qui vont au tas.

Si tel est le cas, il y a très peu ou même presque rien qui va dans la mémoire de la pile.

Je soupçonne que j'ai mal compris quelque chose.

Si presque toutes les données vont à la mémoire de tas, je ne comprends pas l'importance/rôle de la mémoire de pile.

Veuillez expliquer.


Après deux articles explique beaucoup de choses sur la gestion de la mémoire de manière simple.

https://blogs.msdn.microsoft.com/ericlippert/2009/04/27/the-stack-is-an-implementation-detail-part-one/

https://blogs.msdn.microsoft.com/ericlippert/2009/05/04/the-stack-is-an-implementation-detail-part-two/

+0

La pile est principalement destinée aux variables locales et conserve la trace de ces variables dans un arbre d'appels. – juharr

+2

Lire Eric Lippert [La pile est un détail de la mise en œuvre] (https://blogs.msdn.microsoft.com/ericlippert/2009/04/27/the-stack-is-an-implementation-detail-part-one/) . –

+0

Une pile est utile car elle pousse et pops. Ce n'est pas un petit avantage. C'est pourquoi il y a * une * pile. Il arrive * aussi d'être utile dans les scénarios d'allocation de mémoire parfois - et à partir de là l'explication d'Eric Lippert entre en jeu. –

Répondre

9

Ne pensez pas comme "pile" et "tas". Pensez-y comme mémoire à court terme et mémoire à long terme. Maintenant, il devient très facile de savoir ce qui se passe sur la pile et ce qui se passe sur le tas. La durée de vie de la variable est-elle plus longue que l'activation de la méthode actuelle? Si oui, alors ce n'est pas éphémère, et doit aller sur le tas. Si c'est le cas, alors peut aller sur la pile.

Par exemple:

class C { 
    void M() { 
    string s = Whatever(); 
    Something(s); 
    } 
} 

La variable locale s peut aller sur la piscine à court terme car elle ne dure pas plus longtemps que l'activation de la méthode.

Maintenant, vous pourriez dire attendre une minute, la chaîne est un type de référence, donc sûrement il va sur le tas. Et non, ce n'est pas le cas. La chaîne va sur le tas, mais la variable ne contient pas de chaîne. La chaîne est un type de référence donc la variable contient une référence, et une référence peut aller sur la pile. La chose fait référence à est sur le tas, mais la référence elle-même est une valeur, et cela peut aller sur la pile. Alors arrêtez de penser que le type de n'importe quoi détermine où il est stocké. Le type est non pertinent. Les variables de type valeur ou type de référence peuvent aller sur le pool à court terme si elles sont de courte durée, et doivent aller sur le pool à long terme si elles ne le sont pas.

Maintenant, qu'en

class C { 
    void M() { 
    int i = Whatever(); 
    X(() => i) 
    } 
} 

Maintenant, je peux aller sur la pile? Le numéro X peut stocker une copie du délégué transmis, et ce délégué doit connaître la valeur de i, donc la variable doit vivre plus longtemps que l'activation de la méthode M, donc i va sur le pool à long terme. i est sur le tas ici.

Encore une fois, le fait qu'il s'agit d'un int est complètement hors de propos. C'est une variable, elle vit longtemps, donc ça va sur le tas.

Qu'en est-il des champs d'une classe ou des éléments d'un tableau? Ce sont des variables. Ils vivent aussi longtemps que l'instance de classe ou l'instance de tableau vit et, par conséquent, leurs durées de vie ne sont pas prévisibles, et par conséquent, ils vont sur le pool à long terme. Pourquoi avons-nous une piscine à court terme et une piscine à long terme?

Parce que le garbage collector pour le pool à court terme est extrêmement rapide et bon marché par rapport au garbage collector pour la piscine à long terme. Ainsi, nous voulons avoir la possibilité de générer des variables sur le pool à court terme quand nous le pouvons - ce qui est quand leurs durées de vie sont short.

+0

"... La chose à laquelle il se réfère est sur le tas ..." - Pourquoi? Est-il toujours garanti d'être affecté dans le tas? Si j'ai un 'Tuple ' (un type de référence) pourquoi est-il nécessaire d'être alloué dans le tas? –

+2

@LucaCremonesi: Parce que la chose à laquelle il est fait référence * n'est pas connue pour avoir une durée de vie courte *. Maintenant, il y a des scénarios où nous pouvons * savoir * qu'une référence particulière est créée dans une méthode, n'échappe jamais à la méthode, et est donc inutilisée après le retour de la méthode. Dans ces cas, le CLR * pourrait * générer une référence à quelque chose sur la pile. Les implémentations actuelles ne le font pas; Il est moins coûteux et plus facile d'avoir un allocateur et un collecteur pour les types de référence.Mais * en principe * il n'y a pas d'objection à des instances éphémères de types de références. –