スタックとヒープのどちらに何かがあるかを知るにはどうすればよいですか?[複製]

Nov 27 2020

Rustにはさまざまなタイプがあります。スタックとヒープのどちらに何かがあるかを知るにはどうすればよいですか?

構造体を20レベルの深さでネストし、すべてのレベルにスタックデータが含まれているが、レベル20にはヒープボックスが1つある場合、これはツリー全体がヒープ上にあることを意味しますか?

そして、ルートでその構造体がヒープ上のボックス内にある場合はどうでしょうか?すべてのスタックベースのデータがヒープに移動されましたか?

このスタックとヒープロジックを観察するためのツールはありますか?

回答

3 Masklinn Nov 27 2020 at 20:42

Rustにはさまざまなタイプがあります。スタックとヒープのどちらに何かがあるかを知るにはどうすればよいですか?

誰もそれをヒープに置かない場合、それはヒープ上にありません。

構造体を20レベルの深さでネストし、すべてのレベルにスタックデータが含まれているが、レベル20にはヒープボックスが1つある場合、これはツリー全体がヒープ上にあることを意味しますか?

いいえBox、具体的にはヒープポインタです。つまり、ボックス内にあるものはすべてヒープ上にあります。残りはどこに置いてもかまいません(ツリー自体がボックス内にある可能性があり、その時点で、他のヒープ割り当て構造を指すヒープ割り当て構造になります)。

他の一般的なヒープポインタがあるRcArcString、またはVec。そしてもちろん、実際にはポインタHashMapや友人になることなく、ヒープ上で作業を行う、より複雑な構造が他にもあります。

そして、ルートでその構造体がヒープ上のボックス内にある場合はどうでしょうか?すべてのスタックベースのデータがヒープに移動されましたか?

はい。構造の残りの部分は「ルート」の「内部」にあるため、全体をボックス化します。

このスタックとヒープロジックを観察するためのツールはありますか?

あんまり。アロケーターのトレースや、一部のアロケーターのデバッグサポート(jemallocでのヒーププロファイリングなど)などのツールがあり、ヒープ割り当てをトレースできます。しかし、これらはすべて、それらのバイトが正確に何であるかではなく、ある程度のバイトが割り当てられていることを示しています。ヒープ割り当てが行われなかったという推論によって、ヒープ割り当てが行われていないことだけがわかります。

2 PeterHall Nov 27 2020 at 21:07

Linuxでは、あなたがヒープ使用量をプロファイルすることができますvalgrindし、massifとして結果を表示しますms_print

最初にプログラムのプロファイルを作成します。

$ 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==

レポートは、で表示できるmassif.out.<pid>pidプロセスIDは)という名前のファイルに書き込まれますms_print。上記の例では、プロセスIDは32006であるため、次のように表示します。

$ ms_print massif.out.32006

多くの情報が得られますが、ヒープ割り当てが発生する場所と、それらにつながるスタックトレースが示されます。