C# 背景GC:Troelsen
我刚刚在网上读了一个话题,我有点困惑 因此,“Pro C#5.0和.NET 4.5框架”-安德鲁·特罗尔森。引述:C# 背景GC:Troelsen,c#,.net,memory-leaks,garbage-collection,clr,C#,.net,Memory Leaks,Garbage Collection,Clr,我刚刚在网上读了一个话题,我有点困惑 因此,“Pro C#5.0和.NET 4.5框架”-安德鲁·特罗尔森。引述: class Program { static void Main(string[] args) { Console.WriteLine("***** Fun with System.GC *****"); // Print out estimated number of bytes on heap. Console.W
class Program
{
static void Main(string[] args)
{
Console.WriteLine("***** Fun with System.GC *****");
// Print out estimated number of bytes on heap.
Console.WriteLine("Estimated bytes on heap: {0}",
GC.GetTotalMemory(false));
// MaxGeneration is zero based.
Console.WriteLine("This OS has {0} object generations.\n",
(GC.MaxGeneration + 1));
Car refToMyCar = new Car("Zippy", 100);
Console.WriteLine(refToMyCar.ToString());
// Print out generation of refToMyCar.
Console.WriteLine("\nGeneration of refToMyCar is: {0}",
GC.GetGeneration(refToMyCar));
// Make a ton of objects for testing purposes.
object[] tonsOfObjects = new object[50000];
for (int i = 0; i < 50000; i++)
tonsOfObjects[i] = new object();
// Collect only gen 0 objects.
GC.Collect(0, GCCollectionMode.Forced);
GC.WaitForPendingFinalizers();
// Print out generation of refToMyCar.
Console.WriteLine("Generation of refToMyCar is: {0}",
GC.GetGeneration(refToMyCar));
// See if tonsOfObjects[9000] is still alive.
if (tonsOfObjects[9000] != null)
{
Console.WriteLine("Generation of tonsOfObjects[9000] is: {0}",
GC.GetGeneration(tonsOfObjects[9000]));
}
else
Console.WriteLine("tonsOfObjects[9000] is no longer alive.");
// Print out how many times a generation has been swept.
Console.WriteLine("\nGen 0 has been swept {0} times",
GC.CollectionCount(0));
Console.WriteLine("Gen 1 has been swept {0} times",
GC.CollectionCount(1));
Console.WriteLine("Gen 2 has been swept {0} times",
GC.CollectionCount(2));
Console.ReadLine();
}
}
public class Car
{
public int CurrentSpeed { get; set; }
public string PetName { get; set; }
public Car()
{
}
public Car(string name, int speed)
{
PetName = name;
CurrentSpeed = speed;
}
public override string ToString()
{
return string.Format("{0} is going {1} MPH", PetName, CurrentSpeed);
}
}
在这一点上,我希望您对对象生命周期的细节感到更舒服。在下一节中,我们将进一步研究垃圾收集过程,讨论如何构建可终结对象以及一次性对象。请注意,只有在构建维护内部非托管资源的C#类时,通常才需要以下技术
为什么他说CLR在后台执行了大量GC?他是说对象从0代升级到第1代,还是说当应用程序关闭时将收集这些对象?AFAIK在这一点上(在exit Main方法之前)GC只运行了一次,因为我们只有一个显式GC,但隐式GC是不可能的,因为我们正在调用方法。所以,如果我们调用对象的方法,它们肯定是非收集的,如果我们不调用,我们就无法在环境中了解它们。输出还说0代收集了一次,所以他为什么告诉我们执行了多少次GC
我喜欢人们写一些奇怪的、毫无根据的东西,但在说了之后,很明显,
或绝对清晰,那是
等等
好的,我正在增加数组大小,但现在输出是:
***** Fun with System.GC *****
Estimated bytes on heap: 37748
This OS has 3 object generations.
Zippy is going 100 MPH
Generation of refToMyCar is: 0
Generation of refToMyCar is: 0
Generation of tonsOfObjects[9000] is: 0
Gen 0 has been swept 1 times
Gen 1 has been swept 1 times
Gen 2 has been swept 1 times
代码:
static void Main()
{
Console.WriteLine(“*******Fun with System.GC****”);
//打印出堆上的估计字节数。
WriteLine(“堆上的估计字节:{0}”,
GC.GetTotalMemory(假));
//MaxGeneration是基于零的。
Console.WriteLine(“此操作系统有{0}个对象生成。\n”,
(GC.MaxGeneration+1));
Car refToMyCar=新车(“Zippy”,100);
Console.WriteLine(refToMyCar.ToString());
//打印出refToMyCar的生成。
Console.WriteLine(“\n refToMyCar的生成为:{0}”,
GC.GetGeneration(refToMyCar));
//为测试目的制作大量对象。
object[]tonsOfObjects=新对象[5000000];
对于(int i=0;i<50000;i++)
tonsOfObjects[i]=新对象();
//仅收集第0代对象。
GC.Collect(0,GCCollectionMode.Forced);
GC.WaitForPendingFinalizers();
//打印出refToMyCar的生成。
WriteLine(“refToMyCar的生成为:{0}”,
GC.GetGeneration(refToMyCar));
//查看tonsOfObjects[9000]是否仍处于活动状态。
if(tonsOfObjects[9000]!=null)
{
WriteLine(“tonsOfObjects[9000]的生成为:{0}”,
GC.GetGeneration(tonsOfObjects[9000]);
}
其他的
WriteLine(“tonsOfObjects[9000]不再处于活动状态。”);
//打印出一代人被扫荡了多少次。
Console.WriteLine(“\nGen 0已扫描{0}次”,
GC.CollectionCount(0);
WriteLine(“Gen 1已扫描{0}次”,
GC.收集计数(1);
WriteLine(“Gen 2已扫描{0}次”,
GC.收集计数(2);
Console.ReadLine();
}
怎么可能呢?我们有一个GC,但对象并没有升级到第一代 您只创建了价值一磅的对象。你有没有在原代码上抄近路?一些你在汽车课上做过的证明
要创建大量的对象,您需要创建至少2兆字节的对象才能触发gen#0收集。任意改变50000到500000,使之足够。用不同的值进行实验,看看对显示的数字有什么影响。汽车类别可能不同,但输出也是从原始来源提供的,因此他说,该输出包含有关的所有必需信息。现在的汽车等级是原装的(改装的)嗯,他错了。从结果中可以明显看出。请做一个实验,重现观察结果是非常容易的。我照你说的做了,但现在输出比以前更奇怪
***** Fun with System.GC *****
Estimated bytes on heap: 37748
This OS has 3 object generations.
Zippy is going 100 MPH
Generation of refToMyCar is: 0
Generation of refToMyCar is: 0
Generation of tonsOfObjects[9000] is: 0
Gen 0 has been swept 1 times
Gen 1 has been swept 1 times
Gen 2 has been swept 1 times
static void Main()
{
Console.WriteLine("***** Fun with System.GC *****");
// Print out estimated number of bytes on heap.
Console.WriteLine("Estimated bytes on heap: {0}",
GC.GetTotalMemory(false));
// MaxGeneration is zero based.
Console.WriteLine("This OS has {0} object generations.\n",
(GC.MaxGeneration + 1));
Car refToMyCar = new Car("Zippy", 100);
Console.WriteLine(refToMyCar.ToString());
// Print out generation of refToMyCar.
Console.WriteLine("\nGeneration of refToMyCar is: {0}",
GC.GetGeneration(refToMyCar));
// Make a ton of objects for testing purposes.
object[] tonsOfObjects = new object[5000000];
for (int i = 0; i < 50000; i++)
tonsOfObjects[i] = new object();
// Collect only gen 0 objects.
GC.Collect(0, GCCollectionMode.Forced);
GC.WaitForPendingFinalizers();
// Print out generation of refToMyCar.
Console.WriteLine("Generation of refToMyCar is: {0}",
GC.GetGeneration(refToMyCar));
// See if tonsOfObjects[9000] is still alive.
if (tonsOfObjects[9000] != null)
{
Console.WriteLine("Generation of tonsOfObjects[9000] is: {0}",
GC.GetGeneration(tonsOfObjects[9000]));
}
else
Console.WriteLine("tonsOfObjects[9000] is no longer alive.");
// Print out how many times a generation has been swept.
Console.WriteLine("\nGen 0 has been swept {0} times",
GC.CollectionCount(0));
Console.WriteLine("Gen 1 has been swept {0} times",
GC.CollectionCount(1));
Console.WriteLine("Gen 2 has been swept {0} times",
GC.CollectionCount(2));
Console.ReadLine();
}