オブジェクト( )を意味する場合new Foo(i);
、私の理解ではありません。これはスタックに割り当てられることはありません。ただし、第0世代で消滅するため、収集は非常に効率的です。私はCLIの暗くて暗い隅をすべて知っているとは言いませんが、管理された参照型がスタックに割り当てられることにつながるC#のシナリオをstackalloc
認識していません(実際には数えられない、非常に具体的です)。明らかに、C ++にはさらにいくつかのオプションがありますが、それはマネージドインスタンスではありません。
興味深いことに、MonoTouch / AOTではすぐに収集される可能性がありますが、これはメインのCLI VMではありません(非常に特殊なシナリオ用です)。
変数については、通常はスタック上にあります(そして、ループの反復ごとに再利用されます)が、そうではない場合があります。たとえば、これが「イテレータブロック」である場合、削除されていないすべてのローカル変数は、実際にはコンパイラによって生成されたステートマシンのフィールドです。より一般的には、変数が「キャプチャ」される場合(匿名メソッドまたはラムダ式に変換され、どちらもクロージャを形成します)、変数はコンパイラによって生成されたキャプチャコンテキストのフィールドに変換され、ループの反復ごとに分離されます(foo
ループ内で宣言されているため)。これは、それぞれがヒープ上で分離していることを意味します。
i
(ループ変数)に関しては-それがキャプチャされると、さらに興味深いものになります
- C#1.2ではキャプチャは存在しませんでしたが、仕様によれば、ループ変数は技術的には反復ごとです。
- C#2.0から4.0では、ループ変数が共有されます(悪名高いキャプチャ/ foreachの一般的な質問が発生します)
- C#5.0以降では、ループ変数は再び反復されます
これは、変数がキャプチャされたときにのみ違いをもたらしますが、キャプチャコンテキストでの変数の表示方法のセマンティクスを正確に変更します