私が理解しているように、intは値型であるため、スタックに存在します
あなたの理解は間違っています。値型は、値によってコピーされるため、「値型」と呼ばれます。参照型は、参照によってコピーされるため、「参照型」と呼ばれます。「値型が常にスタック上に存在する」というのはまったく真実ではありません。それが本当なら、それらは「スタック型」と「ヒープ型」と呼ばれるでしょう。
真実は、これが実装の詳細であるということです。さまざまなフレームワーク実装が、スタックとヒープを好きなように使用することを選択できます。Microsoftの実装による方法は次のとおりです。
- 参照型の変数の値は、ヒープメモリへの参照です。参照は基本的に32ビットまたは64ビットの整数です。
- 値型の変数の値はその値です。
- ローカル変数の値は、ローカル変数がイテレーターブロック内にあるか、無名メソッドまたはラムダ式の外部変数を閉じていない限り、スタックに格納されます。そのような場合、ローカル変数の値はヒープに格納されます。もちろん、ローカル変数を最適化できない限り、ストレージはまったくありません。または、登録することもできます。その場合、スタックにもヒープにも存在せず、プロセッサレジスタに存在します。
- 参照型のインスタンス変数と静的変数の値はヒープに格納されます。
それは明らかですか?
値型を指しますが、この参照(ヒープ上)ではありませんか?
フィールド「A」は値型です。これはフィールドであるため、その変数はヒープに格納されます。
Class1のインスタンスを作成するときに、そのフィールドタイプもヒープ上に作成されますか?
はい、インスタンス変数のストレージはヒープ上にあります。
しかし、ほとんどの場合、フィールドを使用するにはオブジェクトのインスタンスを作成する必要があるため、実際にスタックにあるのはいつかわかりません。
スタックに載ることはありません。上で述べたように、スタックに配置されるのは、ラムダメソッドまたは匿名メソッドのクローズドオーバーローカルではなく、イテレーターブロックにないローカル変数(およびコンパイラーによって生成された一時変数)だけです。そしてもちろん、ジッターはそれらを完全にスタックから外し、空きレジスターがある場合はそれらをレジスターに入れるために自由です。
しかし、実際には、スタックに何が表示され、ヒープに何が表示されるかを気にする必要があるのはなぜですか。スタックにあるのは、安価にスタックに置くことができるものです。他のすべてはヒープ上にあります。