Почему этот объект не мусор - PullRequest
5 голосов
/ 20 февраля 2012

В следующем фрагменте кода мне интересно, почему testvectors не собирается после вызова функции. Я вижу, что использование памяти увеличивается до 270 МБ, а затем остается там навсегда.

Эта функция вызывается напрямую из 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 ]

9 голосов
/ 20 февраля 2012

Не путайте сборку мусора с подсчетом ссылок.Память освобождается, когда решает среда выполнения, не всегда, когда на нее больше нет ссылок.Цитата:

Сборка мусора происходит, когда выполняется одно из следующих условий:

В системе недостаточно физической памяти.

Память, используемая выделеннымобъекты в управляемой куче превышают приемлемый порог.Это означает, что в управляемой куче превышен порог допустимого использования памяти.Этот порог непрерывно регулируется в процессе работы.

Вызывается метод GC.Collect.Почти во всех случаях вам не нужно вызывать этот метод, потому что сборщик мусора работает непрерывно.Этот метод в основном используется для уникальных ситуаций и тестирования.

Прочтите это, если вам интересно:

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

5 голосов
/ 20 февраля 2012

ГХ может работать, когда захочет.И это может быть намного позже.Нет необходимости освобождать некоторую память непосредственно после того, как исчезнет последняя ссылка.Ваш массив будет собран в следующей коллекции Gen2.

Если вы не будете выделять память, он, скорее всего, никогда не будет работать после возврата из функции.

Вы можете вручную запустить GC с помощью GC.Collect(),но это, как правило, не рекомендуется.

3 голосов
/ 20 февраля 2012

Когда я запускаю это, я наблюдаю обратное:

 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);
            }
        }    
    }
0 голосов
/ 20 февраля 2012

Попробуйте добавить GC.GetTotalMemory (true) до и после использования метода увеличенияMemoryUsage () и сравните числа.

0 голосов
/ 20 февраля 2012

Сборка мусора недетерминирована.GC должен решить, когда это удачный момент для этого.

0 голосов
/ 20 февраля 2012

Скорее всего, ваши тестовые векторы переводятся в кучу больших объектов (LOH), а затем они не собираются во время сбора Gen0.

Хорошая ссылка здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...