Comment savoir si quelque chose se trouve sur la pile ou sur le tas? [dupliquer]
Dans Rust, il existe de nombreux types différents; comment savoir si quelque chose est sur la pile ou sur le tas?
Disons que si j'avais des structures imbriquées de 20 niveaux de profondeur, et que chaque niveau contient des données de pile, mais au niveau 20, il y a une boîte de tas, cela signifie-t-il que l'arbre entier est maintenant sur le tas?
Et si à la racine cette structure se trouve à l'intérieur d'une boîte sur le tas - toutes les données basées sur la pile sont-elles maintenant déplacées vers le tas?
Existe-t-il des outils pour observer cette logique de pile ou de tas?
Réponses
Dans Rust, il existe de nombreux types différents; comment savoir si quelque chose est sur la pile ou sur le tas?
Si personne ne le met sur le tas, ce n'est pas sur le tas.
Disons que si j'avais des structures imbriquées de 20 niveaux de profondeur, et que chaque niveau contient des données de pile, mais au niveau 20, il y a une boîte de tas, cela signifie-t-il que l'arbre entier est maintenant sur le tas?
No. Box
est spécifiquement un pointeur de tas. Donc, tout ce qui est à l'intérieur de la boîte est sur le tas. Le reste est là où vous le placez (l'arbre pourrait lui-même être dans une boîte, à quel point vous auriez une structure allouée en tas pointant vers une autre structure allouée en tas).
D' autres pointeurs tas commun sont Rc
, Arc
, String
ou Vec
. Et bien sûr, il existe d'autres structures plus compliquées qui font leur travail sur le tas sans vraiment être des pointeurs par exemple HashMap
et des amis.
Et si à la racine cette structure se trouve à l'intérieur d'une boîte sur le tas - toutes les données basées sur la pile sont-elles maintenant déplacées vers le tas?
Oui. Puisque le reste de la structure est "à l'intérieur" de la "racine", vous encadrez le tout.
Existe-t-il des outils pour observer cette logique de pile ou de tas?
Pas vraiment. Il existe des outils comme le traçage des allocateurs ou le support de débogage dans certains allocateurs (par exemple le profilage de tas dans jemalloc), qui vous permettent, eh bien, de tracer les allocations de tas. Mais tout cela peut vous dire qu'une certaine quantité d'octets a été allouée, pas ce que sont exactement ces octets, et vous saurez seulement qu'une allocation de tas n'a pas eu lieu par déduction qu'aucune allocation de tas ne s'est produite.
Sous Linux, vous pouvez profiler l'utilisation du tas avec valgrind
et massif
et afficher les résultats avec ms_print
.
Premier profil du programme:
$ valgrind --tool=massif ./target/debug/my_program
==32006== Massif, a heap profiler
==32006== Copyright (C) 2003-2017, and GNU GPL'd, by Nicholas Nethercote
==32006== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==32006== Command: ./target/debug/my_program
==32006==
Le rapport est écrit dans un fichier nommé massif.out.<pid>
(où pid
est l'ID de processus) que vous pouvez afficher avec ms_print
. Dans l'exemple ci-dessus, l'ID de processus est 32006, alors affichez-le avec:
$ ms_print massif.out.32006
Vous obtiendrez beaucoup d'informations, mais cela vous indiquera où les allocations de tas se produisent, avec les traces de pile qui y mènent.