收集仍在范围内的对象 - GC.Collect

时间:2011-06-21 12:14:34

标签: c# .net garbage-collection

我读过这篇文章: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
         * 
         */
    }
}

编辑第一个示例的解决方案:调试模式(不在调试器中运行,但甚至在编译模式下运行)。如果我使用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循环时不会收集垃圾?

2 个答案:

答案 0 :(得分:6)

在对Raymond的文章和Yun Jin的MSDN文章here的评论中提及

  

实际上,对于可调试代码,JIT   将每个变量的生命周期延长到   功能结束。

因此,您的收藏将不会在您发现的调试模式下收集,也不会在发布模式下收集它。

答案 1 :(得分:0)

garbace收藏家的行为不是确定性的,不应该被认为是确定性的。不要依赖GC。

您在问为什么GC 在给定时间点收集您的垃圾。更好的问题是为什么 收集在给定的时间点。