¿Cómo sé si hay algo en la pila o en el montón? [duplicar]
En Rust hay muchos tipos diferentes; ¿Cómo sé si hay algo en la pila o en el montón?
Digamos que si tuviera estructuras anidadas a 20 niveles de profundidad, y cada nivel contiene datos de pila, pero en el nivel 20 hay una caja de pila, ¿significa esto que todo el árbol está ahora en la pila?
¿Y qué pasa si en la raíz esa estructura está dentro de una caja en el montón? ¿Todos los datos basados en la pila ahora se mueven al montón?
¿Hay herramientas para observar esta lógica de pila frente a montón?
Respuestas
En Rust hay muchos tipos diferentes; ¿Cómo sé si hay algo en la pila o en el montón?
Si nadie lo pone en el montón, no está en el montón.
Digamos que si tuviera estructuras anidadas a 20 niveles de profundidad, y cada nivel contiene datos de pila, pero en el nivel 20 hay una caja de pila, ¿significa esto que todo el árbol está ahora en la pila?
No. Box
es específicamente un puntero de montón. Entonces, lo que sea que esté dentro de la caja está en el montón. El resto está donde lo coloque (el árbol podría estar en una caja, en cuyo punto tendría una estructura asignada al montón apuntando a otra estructura asignada al montón).
Otros indicadores del montón común son Rc
, Arc
, String
, o Vec
. Y, por supuesto, hay otras estructuras más complicadas que hacen su trabajo en el montón sin ser realmente indicadores, por ejemplo, HashMap
y amigos.
¿Y qué pasa si en la raíz esa estructura está dentro de una caja en el montón? ¿Todos los datos basados en la pila ahora se mueven al montón?
Si. Dado que el resto de la estructura está "dentro" de la "raíz", encuadras todo.
¿Hay herramientas para observar esta lógica de pila frente a montón?
Realmente no. Hay herramientas como el rastreo de asignadores o el soporte de depuración en algunos asignadores (por ejemplo, la creación de perfiles de montón en jemalloc), que le permiten, bueno, rastrear asignaciones de montón. Pero todo lo que esto puede decirle es que se ha asignado una cierta cantidad de bytes, no cuáles son esos bytes exactamente, y solo sabría que no se ha realizado una asignación de montón por deducción de que no ocurrió ninguna asignación de montón.
En Linux, puede perfilar el uso del montón con valgrind
y massif
y ver los resultados con ms_print
.
Primero perfile el programa:
$ 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==
El informe se escribe en un archivo llamado massif.out.<pid>
(donde pid
está la identificación del proceso) que puede ver con ms_print
. En el ejemplo anterior, el ID del proceso es 32006, así que véalo con:
$ ms_print massif.out.32006
Obtendrá mucha información, pero le indicará dónde ocurren las asignaciones de montón, con los rastros de pila que conducen a ellas.