Я не могу понять немного вещей на Сборке "мусора".
Во-первых, как данные являются выделенным местом? т.е. на стеке или "куче" (Согласно моему знанию, всем статическим или глобальным переменным присваивают пространство на стеке и локальных переменных, присвоены пространство на "куче").
Во-вторых, GC работает на данных по стекам или "куче"? т.е. алгоритм GC как Марк/Развертка относился бы к данным по стеку как корневое право набора? И затем отобразите все достижимые переменные на "куче" путем проверки, какие переменные на "куче" относятся к корневому набору.
Что, если программа не имеет глобальной переменной? Как алгоритм работает затем?
С уважением, негр
Это может помочь уточнить, о GC какой платформы вы спрашиваете - JVM, CLR, Lisp и т. Д. Тем не менее:
Сначала сделаем шаг назад, некоторые локальные переменные обычно размещаются в стеке. Однако особенности могут различаться в зависимости от языка. Чтобы взять C # в качестве примера, в стеке хранятся только локальные типы значений и параметры методов. Так, в C # foo
будет размещаться в стеке:
public function bar() {
int foo = 2;
...
}
В качестве альтернативы динамически выделяемые переменные используют память из кучи. Это должно иметь интуитивно понятный смысл, поскольку в противном случае стек должен был бы динамически расти при каждом вызове new
. Кроме того, это будет означать, что такие переменные могут использоваться только как локальные в локальной функции, которая их распределяет, что, конечно, неверно, потому что мы можем иметь (например) переменные-члены класса. Итак, возьмем другой пример из C #, в следующем случае результат
размещается в куче:
public class MyInt
{
public int MyValue;
}
...
MyInt result = new MyInt();
result.MyValue = foo + 40;
...
Теперь, учитывая этот фон, память в куче собирается сборщиком мусора. Память в стеке не нуждается в сборке мусора, поскольку память будет освобождена при возврате текущей функции. На высоком уровне алгоритм GC работает, отслеживая все объекты, которые динамически размещаются в куче. После выделения через new
объект будет отслеживаться сборщиком мусора и собираться, когда он больше не находится в области видимости и на него больше нет ссылок.
Во-первых, как выделено пространство для данных? то есть в стеке или куче (согласно моим знаниям, всем статическим или глобальным переменным назначается пространство в стеке , а локальным переменным назначается место в стеке назначенное пространство в куче).
Нет, переменные стека - это вызовы методов и локальные переменные. Фрейм стека создается при вызове метода и удаляется при его возврате.
Память в Java и C # выделяется в куче с помощью вызова «new».
Во-вторых, сборщик мусора работает с данными в стеках или кучах? то есть алгоритм GC, такой как Mark / Sweep, будет ссылаться на данные в стеке как на корневой набор, верно? А затем сопоставьте все доступные переменные в куче, проверив, какие переменные в куче ссылаются на корневой набор.
Сборщик мусора используется в куче.
Mark and sweep нельзя рассматривать как передовой алгоритм сборки мусора. И Java, и .NET GC теперь используют модели поколений.
Что делать, если в программе нет глобальной переменной ? Как же тогда работает алгоритм ?
Что означает «глобальная переменная» в таких языках, как Java и C #, где все принадлежит классу?
Корень графа объектов произвольный. Признаюсь, я не знаю, как его выбрали.
Прочтите эту статью . Это очень хороший обзор методов однопроцессорной сборки мусора. Это даст вам базовое понимание и терминологию по GC. Затем прочтите книгу Джонса и Линса «Сборка мусора: алгоритмы автоматического управления динамической памятью». В отличие от обзорной статьи, на которую я указал выше, книга не доступна бесплатно в Интернете; вы должны купить это; Но оно того стоит.
Посмотрите книгу Сборка мусора: алгоритмы автоматического управления динамической памятью .
Ричард и Карл прекрасно продемонстрировали модель памяти Windows, включая модель .NET и GC, в своих .NET Rocks! архивы: