2017-01-07 3 views
1

GCには3世代(0,1,2)の世代がありますが、GCがどのように世代を変数として決定するのか疑問に思っていますか?ガベージコレクションで変数の生成を決定する方法

私はすべての変数が世代0に入り、しばらくして世代1と世代2に移行したと考えました.GCが世代を決定するのは規模の問題ですか?

プログラム1:

private static void Main(string[] args) 
{ 
     int a = 0; 
     string name = "Test"; 
     var byteArray = new byte[10]; 
     byteArray[4] = 4; 

     Console.WriteLine($"Generation of array {GC.GetGeneration(byteArray)}"); 
     Console.WriteLine($"Generation of local int variable {GC.GetGeneration(a)}"); 
     Console.WriteLine($"Generation of local string variable {GC.GetGeneration(name)}"); 
} 

結果

Generation of array 0 
Generation of local int variable 0 
Generation of local string variable 0 

プログラム2:

private static void Main(string[] args) 
{ 
     int a = 0; 
     string name = "Test"; 
     var byteArray = new byte[100000000]; 
     byteArray[4] = 4; 

     Console.WriteLine($"Generation of array {GC.GetGeneration(byteArray)}"); 
     Console.WriteLine($"Generation of local int variable {GC.GetGeneration(a)}"); 
     Console.WriteLine($"Generation of local string variable {GC.GetGeneration(name)}"); 

} 

R彼らはすぐに収集できるように小さいことが

Generation of array 2 
Generation of local int variable 0 
Generation of local string variable 0 
+2

正しく理解しました。オブジェクトは世代0で始まり、時間の経過とともに生き残る世代に移ります。このような巨大なオブジェクトが短命になる可能性は低いという仮説のため、古い世代に直接移動する非常に大きなオブジェクトは例外です。 –

答えて

5

GCが変数の世代をどのように決定するのでしょうか?

変数は最初はGCではありません。 参照型のオブジェクトはGCです。これらのオブジェクトにはの変数が含まれていますが、オブジェクトが収集されています。

私はすべての変数が世代0に行くといくつかの時間後の世代の1と2

号への移行は、変数の観点で考えてはいけないと思いました。オブジェクトの観点から考える。新たに割り当てられたオブジェクトはgen0に入ります。そのオブジェクトがコレクションに残っている場合、そのオブジェクトはgen1に移動されます。別のコレクションで存続する場合、それはgen2に移動します。

これで、intを含むローカル変数でGetGenerationを呼び出すと、常にゼロが返される理由が分かりました。地元が何とか魔法のようにgen0に関連付けられているからではありません。ローカルは参照型のオブジェクトではなく、もその値ではありません!

intをGetGenerationに渡すと、intはオブジェクトに囲まれます。そのオブジェクトは新しく割り当てられているので0世代になります。これは変数については何も教えてくれません。 (非ヌル)の値の型をGetGenerationに渡すと、割り当てがトリガーされ、明らかにその割り当てはgen0になります。

この場合も、ご質問は、GCが寿命の変数を見ていると思われることを示しています。 ではありません。参考タイプのオブジェクトのライフタイムを見ています。

GCは世代を決定するのに問題はありますか?

はい。例えば、非常に大きな配列は、特別な「ラージオブジェクトヒープ」から割り当てられます。 「極端に大きい」とは、基本的に85KB以上のオーダーのオブジェクトを意味します。ラージオブジェクトヒープは、(1)圧縮されておらず、(2)正規のヒープがgen2コレクションを行うときにのみ収集されます。

1

世代0と1の必要性をesult。それらを小さく保つために、非常に大きなオブジェクトが第2世代に直接割り当てられます。

+0

これは正確ではありませんが、近いです。小さなオブジェクトヒープgen2と大きなオブジェクトヒープは異なるヒープです。彼らは同時に収集されます。 'GetGeneration'はラージオブジェクトに対して2を返しますが、小さなオブジェクトと同じヒープ上にあることを意味しません。 –

+0

問題はGen1にオブジェクトが入ることです。以下の結果を参照してください。 @E var byteArray = new byte [84987]; //世代を取得する var byteArray =新しいバイト[84988]; //世代2を取得する –

+0

世代0のオブジェクトは、世代0のコレクションで存続すると世代1になります。 –

関連する問題