为什么这个对象不是垃圾收集的

时间:2012-02-20 13:46:06

标签: c# garbage-collection

在下面的代码段中,我想知道为什么函数调用后没有收集testvectors。我看到内存使用量高达270Mb,然后永远呆在那里。

此功能直接从Main。

调用
private static void increaseMemoryUsage()
{
    List<List<float>> testvectors = new List<List<float>>();
    int vectorNum = 250 * 250;
    Random rand = new Random();

    for (int i = 0; i < vectorNum; i++)
    {
        List<Single> vec = new List<Single>();

        for (int j = 0; j < 1000; j++)
                {
            vec.Add((Single)rand.NextDouble());
        }
        testvectors.Add(vec);
    }
}

6 个答案:

答案 0 :(得分:9)

不要将垃圾收集与引用计数混淆。运行时决定释放内存,而不是总是在不再引用内存时释放内存。引用:

  

当满足下列条件之一时,就会发生垃圾收集   真:

     

系统物理内存较低。

     

托管堆上已分配对象使用的内存   超过可接受的门槛。这意味着一个门槛   托管堆上已超出可接受的内存使用量。这个   随着过程的进行,阈值会不断调整。

     

调用GC.Collect方法。在几乎所有情况下,你都没有   调用此方法,因为垃圾收集器连续运行。   此方法主要用于独特的情况和测试。

如果您有兴趣,请阅读此内容:

http://msdn.microsoft.com/en-us/library/0xy59wtx.aspx

答案 1 :(得分:5)

GC可以在需要时运行。这可能会晚得多。在最后一次引用消失后,没有义务直接释放一些内存。您的阵列将在下一代Gen2集合中收集。

除非你继续分配内存,否则在函数返回后它可能永远不会运行。

您可以使用GC.Collect()手动触发GC,但通常不鼓励这样做。

答案 2 :(得分:3)

当我跑这个时,我观察到相反的情况:

 class Program
    {
        static void Main(string[] args)
        {
            increaseMemoryUsage();

            Console.WriteLine("Hit enter to force GC");
            Console.ReadLine();

            GC.Collect();

            Console.ReadLine();
        }

        private static void increaseMemoryUsage()
        {
            var testvectors = new List<List<float>>();
            const int vectorNum = 250 * 250;
            var rand = new Random();

            for (var i = 0; i < vectorNum; i++)
            {
                var vec = new List<Single>();

                for (var j = 0; j < 1000; j++)
                    vec.Add((Single)rand.NextDouble());

                testvectors.Add(vec);
            }
        }    
    }

答案 3 :(得分:0)

最有可能的是,您的测试向量会被提升为大对象堆(LOH),然后在Gen0集合期间不会收集它。

良好的链接here

答案 4 :(得分:0)

垃圾收集是不确定的。由GC决定何时是一个好时机。

答案 5 :(得分:0)

尝试在increaseMemoryUsage()方法使用之前和之后添加GC.GetTotalMemory(true)并比较数字。