C # Сборка мусора - PullRequest
       26

C # Сборка мусора

4 голосов
/ 01 октября 2011

скажем, у нас есть:

public void foo()
{
   someRefType test = new someRefType ();
   test = new someRefType ();
}

Что делает сборщик мусора с первым объектом кучи? Это сразу мусор перед новым назначением? Каков общий механизм? Спасибо, Юрген

Ответы [ 4 ]

14 голосов
/ 01 октября 2011

Что делает сборщик мусора с первым объектом кучи?

Кто знает? Это не детерминистично. Думайте об этом так: в системе с бесконечной памятью сборщик мусора не имеет , чтобы делать что-либо . И вы можете подумать, что это плохой пример, но это то, что сборщик мусора имитирует для вас: система с бесконечной памятью. Поскольку в системе с достаточным объемом доступной памяти, чем требуется вашей программе, сборщик мусора никогда не должен запускаться . Следовательно, ваша программа не может делать какие-либо предположения о том, когда будет (если когда-либо) получена память.

Итак, ответ на ваш вопрос: мы не знаем.

Это сразу мусор перед новым назначением?

Нет. Сборщик мусора не является детерминированным. Вы понятия не имеете, когда он будет собирать и выпускать мусор. Вы не можете делать какие-либо предположения о том, когда будет собираться мусор или когда будут работать финализаторы.

На самом деле очень маловероятно, что он собирается так быстро (что может привести к тому, что коллекции будут происходить слишком часто). Кроме того, в системе с достаточным объемом памяти сборщик мусора никогда не должен запускаться .

Что такое общий механизм?

Это довольно широкий вопрос. Но основной принцип очень прост: сборщик мусора имитирует машину с бесконечной памятью. Для этого он каким-то образом отслеживает память и может определить, когда память является мусором. Когда он сочтет нужным, из-за необходимости имитировать бесконечную память, он будет время от времени собирать этот мусор и снова делать его доступным для выделения.

4 голосов
/ 01 октября 2011

Нет, ничто не говорит о том, что объект немедленно собран.На самом деле, вряд ли это так.В конце концов он будет собран сборщиком мусора, но вы не можете точно знать, когда.

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

Точно, как сборка мусора работает, довольно большая тема, но есть отличная документация, которую вы можете читать по MSDN .

1 голос
/ 01 октября 2011

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

.NET имеет так называемый «сборщик мусора», и я думаю, что он ведет себя так же, как и я сам. Я позволяю грязной одежде и почте («объекты C #») накапливаться по всему полу моей гостиной («память») в течение нескольких дней, и когда я обнаруживаю, что больше не вижу ковер («память заполнена») Я провожу некоторое время, убирая («сбор мусора») в гостиной («поколение 0»), выбрасывая ненужные объекты («больше не достижимы») и перемещая оставшиеся в мою спальню ( "поколение 1"). Довольно часто это отнимает у меня время, и мне больше не нужно делать работу. Но когда моя спальня заполняется, я делаю что-то подобное, выбрасывая некоторые предметы и перемещая другие в подвал («поколение 2»). Иногда даже подвал заполняется, и тогда у меня возникает реальная проблема, и мне нужно провести серьезную весеннюю уборку («полный сбор»).

Применяя эту метафору к вашему примеру, мы могли бы догадаться, что первый кусок мусора ("объект кучи") просто сидит, пока я не собираюсь его собирать ("запустить сборщик 0-го поколения"), который происходит, когда я чувствую нравится, когда пол полностью покрыт или, может быть, никогда: -)

0 голосов
/ 25 июня 2016

Чтобы увидеть, когда объекты удаляются, вы можете переопределить метод finalize в своем классе, чтобы напечатать, когда и какие объекты удаляются, как в следующем примере:

class MyClass
{
    private int _id;

    public MyClass(int id)
    {
        _id = id;
    }

    ~MyClass()
    {
        Console.WriteLine("Object " + _id + " deleted at " + DateTime.Now + " .");
    }
}

class Program
{
    static void Main(string[] args)
    {
        MyClass p1 = new MyClass(1);
        p1 = new MyClass(2);

        Console.ReadKey();
    }
}

Чтобы заставить сборщик мусора быстрее освобождать эти объекты, вы можете добавить к ним поле в виде длинного массива, например, private int []memory; и в конструкторе: memory=new int[10000000].

...