Como posso saber se algo está na pilha ou no heap? [duplicado]

Nov 27 2020

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

3 Masklinn Nov 27 2020 at 20:42

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, HashMape 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.

2 PeterHall Nov 27 2020 at 21:07

No Linux, você pode criar o perfil de uso de heap com valgrinde massife 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.