Pan*_*wat 1 c# garbage-collection memory-management
我知道GC有3(0,1,2)代,但我想知道GC如何决定变量的生成?
我认为所有变量都进入第0代,经过一段时间后转移到第1代和第2代.对于GC来说,决定生成是否重要?
PROGRAM1:
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)}");
}
Run Code Online (Sandbox Code Playgroud)
结果
Generation of array 0
Generation of local int variable 0
Generation of local string variable 0
Run Code Online (Sandbox Code Playgroud)
程序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)}");
}
Run Code Online (Sandbox Code Playgroud)
结果
Generation of array 2
Generation of local int variable 0
Generation of local string variable 0
Run Code Online (Sandbox Code Playgroud)
我想知道GC如何决定变量的生成?
变量首先不是GC'd.引用类型的对象是GC'd.这些对象包含变量,但它是收集的对象.
我认为所有变量都进入第0代,经过一段时间后转移到第1代和第2代.
不.不要考虑变量.从对象的角度思考.新分配的对象进入gen0.如果该对象在集合中存活,则将其移至gen1.如果它在另一个集合中存活,它将移至gen2.
所以现在您知道为什么调用GetGeneration包含int的局部变量将始终返回零.这不是因为本地与gen0神奇地联系在一起.本地不是引用类型的对象,它的值也不是!
当你将int传递给int时,GetGeneration将盒子装入一个对象; 该对象是新分配的,因此它在第0代.这告诉您关于该变量的任何信息.如果您将任何(非null)值类型传递给GetGeneration触发分配,显然该分配是gen0.
同样,您的问题表明您认为GC正在查看变量的生命周期.事实并非如此.它正在查看引用类型对象的生命周期.
GC决定这一代的尺寸是否重要?
是.例如,非常大的数组是从特殊的"大对象堆"中分配的."非常大",我们的意思是基本上任何大约85KB或更大的对象.大对象堆是(1)未压缩,(2)仅在常规堆执行gen2集合时收集.