2017-02-05 8 views
4

Comment puis-je prouver que la boxe provoque le stockage d'une variable dans le tas au lieu de la pile?Comment puis-je prouver que la boxe provoque le stockage d'une variable dans le tas au lieu de la pile?

boxing

Je veux un code pour montrer à mes élèves que la boxe cause de stocker une variable tas au lieu de la pile.

Boxing and Unboxing

+3

Est-il même possible de montrer cela de manière concluante dans le code managé? Les stratégies de gestion de la mémoire sont supposées être "invisibles" au code de l'application. Peut-être que vous devez sortir du "bac à sable de code" et regarder des choses comme des vidages mémoire du système d'exécution? – Thilo

+1

Quel est le problème avec l'image que vous avez déjà? Je pense que tout code qui prouverait qu'il est dans le tas serait plus difficile à comprendre pour l'étudiant que le directeur général. – juharr

+3

Utilisez le débogueur, Débogage> Windows> Mémoire> Mémoire 1. Mettez 'O' dans la zone Adresse. Affiche l'adresse où l'objet est stocké, comparez-la à l'adresse d'une autre variable d'objet, dites 'objet O2 = nouvel objet();'. Ils sont très proches les uns des autres, cela le prouve. De même, mettez '& j' dans la zone Adresse. Comparez à la valeur des registres EBP et ESP affichés par Debug> Windows> Registers. Presque la même chose, prouve que la variable unboxed est stockée sur la pile. –

Répondre

0

Il est étonnamment difficile de faire la distinction entre les tas et les objets pile (ce qui est intentionnel, parce que .NET veut cacher ce détail de la mise en œuvre des programmeurs).

Une approche que vous pourriez prendre est de comparer default hash codes basée sur l'adresse d'objets en boîte, et d'observer qu'ils ne cessent de changer (demo):

static object MakeBoxed() { 
    int n = 5; 
    object a = n; 
    return a; 
} 
public static void Main() { 
    for (int i = 0 ; i != 10 ; i++) { 
     object a = MakeBoxed(); 
     Console.WriteLine(RuntimeHelpers.GetHashCode(a)); 
    } 
} 

objets créés à l'intérieur MakeBoxed ne peut pas être sur la pile, car la pile La trame de MakeBoxed est désactivée après l'appel. En outre, ils ne peuvent pas être dans le cadre de la pile Main, car les cadres de pile ne se développent pas, mais tous les objets ont des adresses différentes (codes de hachage par défaut).

+1

Vous observez le même comportement lorsque vous modifiez 'MakeBoxed' en retournant simplement un' int' sans boxe. Pire, vous obtenez le même comportement en écrivant 'var a = 5;' sans aucun appel de méthode. J'ai l'impression qu'il est impossible de faire la différence simplement parce que le tas et la pile sont des détails d'implémentation. – Rob

+1

@Rob Si vous renvoyez un 'int', la boxe aura lieu quand vous appellerez' RuntimeHelpers.GetHashCode (object) '. L'écriture de 'object a = 5' effectue aussi la boxe, il n'est donc pas surprenant que vous obteniez le même comportement. – dasblinkenlight

+0

@dasblinkenlight Pourquoi 'RuntimeHelpers.GetHashCode()' renvoie une valeur différente pour un objet à chaque fois? –