【发布时间】:2019-10-25 10:25:35
【问题描述】:
我是 .NET 和 CLR 的新手,只是关于 CLR 垃圾收集的问题。
我的教科书描述了使用 GC.Collect() 的目的之一是
您的应用程序刚刚分配完大量的对象 并且您希望尽快删除尽可能多的已获取内存。
下面是我的代码:
Console.WriteLine("Estimated bytes on heap: {0}", GC.GetTotalMemory(false));
Car refToMyCar = new Car();
Console.WriteLine("\nGeneration of refToMyCar is: {0}", GC.GetGeneration(refToMyCar));
GC.Collect(0, GCCollectionMode.Forced);
Console.WriteLine("\nGeneration of refToMyCar is: {0}", GC.GetGeneration(refToMyCar));
Console.WriteLine("Estimated bytes on heap: {0}", GC.GetTotalMemory(false));
结果是:
Estimated bytes on heap: 29900
Generation of refToMyCar is: 0
Generation of refToMyCar is: 1
Estimated bytes on heap: 39648
所以这是我的问题:
1- GC.Collect() 似乎仅将 refToMyCar 指向的项目从第 0 代标记到第 1 代,没有任何东西是“免费的”,因为第 1 代意味着一个在垃圾收集中幸存下来的对象。假设在 GC.Collect() 之前,堆上还有 10mb 可用大小(例如总共 100mb),而在 GC.Collect() 之后,堆上仍然只剩下 10mb,那么调用 GC 有什么意义。收藏()?我们不希望可用大小为 100mb 100% 可用吗?
编辑: 放弃我之前的问题
如果我把它改成对象数组,那就更奇怪了:
Console.WriteLine("Estimated bytes on heap: {0}", GC.GetTotalMemory(false));
object[] refToMyCar = new object[50000];
for (int i = 0; i < 50000; i++)
refToMyCar[i] = new object();
Console.WriteLine("\nGeneration of refToMyCar is: {0}", GC.GetGeneration(refToMyCar));
Console.WriteLine("Estimated bytes on heap: {0}", GC.GetTotalMemory(false));
输出是:
Estimated bytes on heap: 29900
Generation of refToMyCar is: 2
Estimated bytes on heap: 836140
Press any key to continue . . .
为什么 refToMyCar 是第 2 代,它是一个在不止一次垃圾收集器扫描中幸存下来的对象?我们还没有调用任何隐式或显式 GC.Collect() 吗?
【问题讨论】:
-
No Disrespect 但是你每天要问这些问题很多次,所有这些问题都可以研究(看起来你有能力)而不是在这里问,大多数这些问题之前已经被问过很多次了,通常有博客和其他站外资源,比这种问答形式能给你更深入的知识和更好的理解
-
另外你居然一问三问,不服
-
I'm new to .NET and CLR冒着听起来粗鲁的风险,请等待一年后再调查GC.Collect()。您需要手动调用它的情况非常少见——而且您不太可能在您正在进行的开发中遇到其中一种情况。现在,你的心智模型应该是“让 GC 做它的事——我会不管它的”。我们可以为您的每一个问题提供详细的答案 - 但老实说,它现在会让您不知所措。 GC 的更多细节花了数年时间才在我的脑海中浮现。 -
I have one year of C# development experience1 个月或 1 年 - 没有区别。再等一两年。 ;)OK, I just want to know why refToMyCar is generation 2, shouldn't it be generation 0?它在哪里承诺它将成为第 0 代?另外,请阅读 Large Object Heap。同样,我强烈建议将其搁置一两年,然后再重新考虑。
标签: c# .net garbage-collection operating-system