Como posso saber se algo está na pilha ou no heap? [duplicado]
Em Rust, existem muitos tipos diferentes; como faço para saber se algo está na pilha vs heap?
Digamos que se eu tivesse structs aninhados com 20 níveis de profundidade e cada nível contivesse dados de pilha, mas no nível 20 haja uma caixa de heap, isso significa que a árvore inteira está agora na pilha?
E se na raiz essa estrutura estiver dentro de uma caixa no heap - todos os dados baseados em pilha agora são movidos para o heap?
Existem ferramentas para observar essa lógica de pilha versus pilha?
Respostas
Em Rust, existem muitos tipos diferentes; como faço para saber se algo está na pilha vs heap?
Se ninguém colocar na pilha, não está na pilha.
Digamos que se eu tivesse structs aninhados com 20 níveis de profundidade e cada nível contivesse dados de pilha, mas no nível 20 haja uma caixa de heap, isso significa que a árvore inteira está agora na pilha?
No. Box
é especificamente um ponteiro de heap. Portanto, o que quer que esteja dentro da caixa está na pilha. O resto está onde quer que você o coloque (a própria árvore poderia estar em uma caixa, em cujo ponto você teria uma estrutura alocada por heap apontando para uma outra estrutura alocada por heap).
Outros ponteiros heap comuns são Rc
, Arc
, String
, ou Vec
. E, claro, há outras estruturas mais complicadas que fazem seu trabalho na pilha sem realmente serem indicadores, por exemplo, HashMap
e amigos.
E se na raiz essa estrutura estiver dentro de uma caixa no heap - todos os dados baseados em pilha agora são movidos para o heap?
Sim. Como o resto da estrutura está "dentro" da "raiz", você encaixota a coisa inteira.
Existem ferramentas para observar essa lógica de pilha versus pilha?
Na verdade não. Existem ferramentas como rastrear alocadores ou suporte para depuração em alguns alocadores (por exemplo, perfil de heap em jemalloc), que permitem rastrear alocações de heap. Mas tudo isso pode lhe dizer que alguma quantidade de bytes foi alocada, não o que esses bytes são exatamente, e você só saberia que uma alocação de heap não aconteceu por dedução de que nenhuma alocação de heap aconteceu.
No Linux, você pode criar o perfil de uso de heap com valgrind
e massif
e visualizar os resultados com ms_print
.
Primeiro perfil do 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==
O relatório é gravado em um arquivo denominado massif.out.<pid>
(onde pid
é o ID do processo) com o qual você pode visualizar ms_print
. No exemplo acima, o ID do processo é 32006, portanto, visualize-o com:
$ ms_print massif.out.32006
Você obterá muitas informações, mas isso o indicará onde ocorrem as alocações de heap, com os rastreamentos de pilha que levam a elas.