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

89
16 октября 2019, 00:10

изучаю сборку мусора в C#. Узнал что сборка происходит в три этапа

  • Маркировка
  • Сборка
  • Сжатие

Перед маркировкой строится граф ссылок где корнем может быть локальные переменные, статические. Все объекты которые входят в этот граф помечаются как используемые и они не подвергаются сборке мусора. Так же можно выделить понятие как активные и не активные корни.


Активные корни - это объекты на которые есть ссылки к примеру от статических переменных, локальных.
Не активные корни - (обновленно) такого понятия не может быть.

Так вот мне интересно уничтожаются ли не активные корни? Или может уничтожаются но не все, к примеру локальные прееменные да, а статические нет. Правильно ли я все расписал (я упустил специально некоторые подробности такие как поколения дабы не перегружать вопрос) ?

Что к примеру произойдет с ссылкой A? Если бы к примеру на объект D не было ссылки, он бы считался недостижимым обектом и был бы удален, но он не корень.



Вот здесь поднималась похожая тема Как CLR проверяет корни и объекты, на которые они (корни) ссылаются?

Answer 1

Корни — это объекты, с которых начинает строиться граф объектов.

Корни могут быть только активными, потому что сборщик мусора не строит графы неактивных объектов. Те, что в конце оказались непомеченными, те и есть неактивные.

Рассмотрим пример со статическим свойством.

public class Foo
{
    public static Bar Bar { get; set; } = new Bar();
}
public class Bar
{
    public string Baz { get; set; }
    public string Qux { get; set; }
    . . .
}

Здесь Foo.Bar — статическое свойство, в котором хранится ссылка на объект Bar, где находятся строки Baz и Qux.

При сборке мусора Foo.Bar это активный корень, и все объекты, доступные из него, будут считаться используемыми.

Обнулим свойство:

Foo.Bar = null;

У нас в памяти остались объект Bar, и строки Baz и Qux. Но теперь на них нет ссылок ниоткуда. Когда сборщик мусора в следующий раз будет строить граф используемых объектов, он их не найдёт и не пометит.

Поэтому сборщик очистит память, которую занимают все три объекта. Важно помнить, что адрес объекта Bar в этот момент не хранится ни в статическом поле, ни в локальной переменной. И — по определению — он уже не корень.

Answer 2

Имхо, нет такого понятия, как "неактивные корни" так как корень у приложения один. Правильнее говорить "недостижимые объекты из корня приложения."

Статика не очищается. Очистка статики происходит лишь при выгрузке домена.

Ресурсы системы тоже автоматически не вычитаются => если взяли какой-то дескриптор у системы через WinAPI, то вы должны его вернуть. В противном случае утечка ресурсов.

Так же очистке локальных переменных препятствует конструкция fixed, которая заставляет сборщик мусора обруливать эти участки, так как там идет прямая работа с указателями под ответственностью программиста.

READ ALSO
Работа с файлами большого объема C#

Работа с файлами большого объема C#

Есть скаченный csv файл объемом 1,5 гигабайтаВ нем содержится примерно 120 000 000 строк в формате xxxx,yyyyyy

106
C# Windows form. CheckBox [закрыт]

C# Windows form. CheckBox [закрыт]

Как сделать, чтобы если один чекбокс активен, при нажатии на другой выбирался этот чекбокс, а с прежнего галочка удалялась?

122
Как создать нумерованный список в Microsoft Word c#?

Как создать нумерованный список в Microsoft Word c#?

Нужно создать нумерованный список в Word, например:

122
Тип DataRepeater существует в двух библиотеках

Тип DataRepeater существует в двух библиотеках

Столкнулся с проблемой, что Тип DataRepeater существует в двух библиотеках, но по сути это одна

89