簡體   English   中英

為什么這個對象不是垃圾收集的

[英]Why is this object not garbage collected

在下面的代碼段中,我想知道為什么函數調用后沒有收集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);
    }
}

不要將垃圾收集與引用計數混淆。 運行時決定釋放內存,而不是總是在不再引用內存時釋放內存。 報價:

當滿足下列條件之一時,將發生垃圾收集:

系統物理內存較低。

托管堆上已分配對象使用的內存超過可接受的閾值。 這意味着托管堆上已超出可接受內存使用量的閾值。 在該過程運行時不斷調整該閾值。

調用GC.Collect方法。 幾乎在所有情況下,您都不必調用此方法,因為垃圾收集器會持續運行。 此方法主要用於獨特的情況和測試。

如果您有興趣,請閱讀此內容:

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

GC可以在需要時運行。 這可能會晚得多。 在最后一次引用消失后,沒有義務直接釋放一些內存。 您的陣列將在下一代Gen2集合中收集。

除非你繼續分配內存,否則在函數返回后它可能永遠不會運行。

您可以使用GC.Collect()手動觸發GC,但通常不鼓勵這樣做。

當我運行時,我觀察到相反的情況:

 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);
            }
        }    
    }

最有可能的是,您的測試向量將被提升為大對象堆(LOH),然后在Gen0集合期間不會收集它。

好的鏈接在這里

垃圾收集是不確定的。 由GC來決定何時是一個好時機。

嘗試在increaseMemoryUsage()方法使用之前和之后添加GC.GetTotalMemory(true)並比較數字。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM