Приводит ли установка объекта к нулю, сборщик мусора С# освобождает занимаемую им память?

У меня есть метод, который вызывается много раз, неоднократно.

public FilesCollection loadCollectionFromDirectory(string directory) 
        {
            string errorMessage;
            FilesCollection collection = new FilesCollection(_collectionType);

            string[] files = Directory.GetFiles(directory);
            foreach (string file in files)
            {
                if(file.EndsWith(".dll"))
                    collection.AddNewFileToCollection(file, out errorMessage);
            }
            files = null;
            return collection;
        }

Я почти уверен, что метод, вызывающий этот метод, поглощает тонну памяти из-за массива строк, который инициализируется каждый раз, когда этот метод запускается. Насколько я понимаю, каждый раз, когда этот метод запускается снова, массив строк устанавливается в новую коллекцию строк, а старые строки остаются в памяти, пока до них не доберется сборка мусора. Это правильно? Насколько я могу судить, сборка мусора до них не доходит достаточно быстро. Есть множество других проблем, влияющих на исключение Out Of Memory, которое я получаю, но я думаю, что слишком много «призрачных строк» ​​является одной из серьезных причин. Если я установлю files = null, как я делаю сейчас, приведет ли это к более раннему выполнению GC? Я неправильно понял основы сборки мусора и управления памятью?

Я полагаю, мой самый большой вопрос: если я снова и снова выполняю string[] files = Directory.GetFiles(directory), ничего не делая с массивом, не приведет ли это к тому, что моя система будет забита кучей строк-призраков?


person HandleThatError    schedule 08.12.2015    source источник
comment
Возможный дубликат C#: следует ли присваивать объектным переменным значение null?   -  person Mark Pattison    schedule 09.12.2015
comment
Массив, на который ссылается files, становится недостижимым в одно и то же время... в последний раз, когда цикл читает из него. Он уже подлежит сбору до того, как будет достигнута ваша files = null; строка.   -  person Ben Voigt    schedule 09.12.2015
comment
@BenVoigt Значит, он должен собираться автоматически? Согласно инструменту профилирования памяти внутри Visual Studio, одна из проблем с моей системой заключается в том, что в ходе выполнения программы выделяется много типов строк. Я думаю, что это часть проблемы, с которой я сталкиваюсь, когда система зависает после исключения Out Of Memory.   -  person HandleThatError    schedule 09.12.2015
comment
@HandleThatError Но ваша проблема не в опубликованном вами коде. Как мы можем помочь исправить это?   -  person Eser    schedule 09.12.2015
comment
@Eser Понятно, я продолжу поиск в кодовой базе. Я думаю, что мне нужно сделать шаг назад и узнать, как объекты выделяются и освобождаются, и как правильно инициализировать объекты, чтобы не осталось призраков.   -  person HandleThatError    schedule 09.12.2015
comment
Если объект выходит за пределы области видимости, память будет восстановлена ​​всякий раз, когда сборщик мусора сочтет это нужным. В случае вашего массива файлов он выйдет за рамки при выходе из метода, поэтому нет необходимости устанавливать для него значение NULL, поскольку на него больше нет ссылок. Что происходит с той FilesCollection, которую вы возвращаете?   -  person Mark    schedule 09.12.2015
comment
Да, как и спросил Марк, что происходит с той FilesCollection, которую вы возвращаете? Вы можете это объяснить?   -  person Dieter Meemken    schedule 09.12.2015
comment
Он передается как пользовательская коллекция, и в зависимости от того, что происходит в приложении, каждый файл может обрабатываться в своем собственном потоке, или коллекция может просто храниться под рукой, чтобы проверить, существует ли в коллекции определенный файл или каталог. . Это не просто одна вещь. Трудно сказать, что происходит в целом, так как это большая кодовая база.   -  person HandleThatError    schedule 09.12.2015
comment
Ах, как пахнет, тебе не кажется. Может быть, он очень долгоживущий, даже в разных темах.   -  person Dieter Meemken    schedule 09.12.2015
comment
Я впервые работаю с утечкой памяти, и это довольно неприятная проблема, которую четыре инженера до меня не могли понять, так что да, я действительно думаю, что чувствую неприятный запах, доносящийся вокруг.   -  person HandleThatError    schedule 09.12.2015
comment
Итак, вы можете предоставить больше кода или это выходит за рамки? Тогда удачи...   -  person Dieter Meemken    schedule 09.12.2015
comment
Учитывая, что мой инструмент профилирования показывает, что некоторые из самых тяжелых выделений происходят на уровне CLR .dll... я бы сказал, что это выходит за рамки. :(   -  person HandleThatError    schedule 09.12.2015


Ответы (2)


Создание files = null сделает коллекцию строк доступной для сборки мусора, но не сразу освободит память. Сборщик мусора вызывается при нехватке памяти. Если область действия функции file[] слишком велика, одним из способов будет получить только те файлы, которые вам нужны.

    public FilesCollection loadCollectionFromDirectory(string directory) 
    {
        string errorMessage;
        FilesCollection collection = new FilesCollection(_collectionType);

        string[] files = Directory.GetFiles(directory,"*.dll");
        foreach (string file in files)
        {
           collection.AddNewFileToCollection(file, out errorMessage);
        }
       // files = null;
        return collection;
    }

Независимо от того, сделаете ли вы это null или нет, по мере того, как область действия функции заканчивается, локальная переменная files будет доступна для сборки мусора.

person goeldeepika3    schedule 08.12.2015
comment
Хорошее предложение относительно второго аргумента GetFiles. Я попробую. - person HandleThatError; 09.12.2015
comment
@HandleThatError Кроме того, если вы работаете с большими наборами файлов, Directory.EnumerateFiles может быть более эффективным, чем Directory.GetFiles. - person vesan; 09.12.2015

Я не уверен, но почему бы вам не попробовать использовать List<string> вместо string[]. Это должно помочь с памятью :) Пожалуйста, дайте мне знать, если это сработало для вас.

person test player    schedule 08.12.2015
comment
Это не повлияет на потребление памяти, так как List<T> по сути является оберткой вокруг массива, и все элементы останутся в памяти. - person Martin Wiboe; 09.12.2015
comment
Спасибо, я всегда думал, что Список немного лучше, когда вы говорите о памяти :) - person test player; 09.12.2015