【发布时间】:2011-09-19 11:36:13
【问题描述】:
我已经阅读了这篇文章:http://blogs.msdn.com/b/oldnewthing/archive/2010/08/10/10048149.aspx,老实说,我并不了解每一个细节。据我了解,即使我没有将 c 设置为 null,也应该在下面的代码中收集 c。另一件事是,只要我们在同一函数的范围内,在 foreach 期间发生的分配似乎就不会被释放。 (见下例)
class Program
{
public class SomeClass
{
public byte[] X;
public SomeClass()
{
X = new byte[1024 * 1024 * 100];
X[155] = 10;
}
}
static void Main()
{
Console.WriteLine("Memory: " + GC.GetTotalMemory(false));
SomeClass c;
c = new SomeClass();
Console.WriteLine("Memory: " + GC.GetTotalMemory(false));
GC.Collect();
Console.WriteLine("Memory: " + GC.GetTotalMemory(true));
Console.ReadKey();
/*
* Output:
*
* Memory: 186836
* Memory: 105044468
* Memory: 104963676
*
*/
}
}
EDIT 第一个示例的解决方案:调试模式(不在调试器中运行,甚至在编译模式中运行)。如果我使用 Release,它将按预期工作:即使没有设置为 null,也会收集 c。第二个例子同样适用。
第二个例子
static void Main(string[] args)
{
Console.WriteLine("Startup Memory: " + GC.GetTotalMemory(false));
var obj = BOObject.Get();
Console.WriteLine("Fetched Object: " + GC.GetTotalMemory(false));
GC.Collect();
Console.WriteLine("Fetched Object (Collected): " + GC.GetTotalMemory(false));
foreach (var node in obj.Traverse())
{
string name = node.Name;
}
Console.WriteLine("Traversed: " + GC.GetTotalMemory(false));
GC.Collect();
Console.WriteLine("Traversed (collected): " + GC.GetTotalMemory(false));
obj = null;
GC.Collect();
Console.WriteLine("collected: " + GC.GetTotalMemory(true));
Console.Read();
}
输出:
启动内存:193060 获取:8972464 获取(收集):5594308 遍历:272553096 遍历(收集):269564660 收集到:269564048
如果我将 foreach 循环放在另一个函数中并调用此函数,.Collect 调用后使用的内存约为 5800000。那么为什么当我在同一个函数中使用 foreach 循环时没有收集垃圾?
【问题讨论】:
标签: c# .net garbage-collection