Вывоз мусора - PullRequest
       34

Вывоз мусора

8 голосов
/ 28 февраля 2010

Я не могу понять кое-что о сборке мусора.

Во-первых, как распределяются данные? т.е. в стеке или в куче (насколько мне известно, всем статическим или глобальным переменным назначается пространство в стеке, а локальным переменным - пространство в куче).

Во-вторых, GC работает с данными в стеках или кучах? Т.е. алгоритм GC, такой как Mark / Sweep, будет ссылаться на данные в стеке как на корневой набор, верно? Затем сопоставьте все достижимые переменные в куче, проверив, какие переменные в куче ссылаются на корневой набор.

Что если в программе нет глобальной переменной? Как тогда работает алгоритм?

С уважением, Негр

Ответы [ 6 ]

11 голосов
/ 28 февраля 2010

Это может помочь уточнить, о какой платформе GC вы спрашиваете - JVM, CLR, Lisp и т. Д. Это говорит:

Сначала, чтобы сделать шаг назад, определенные локальные переменные обычно располагаются в стеке. Однако специфика может отличаться в зависимости от языка. Чтобы взять C # в качестве примера, в стеке хранятся только локальные типы значений и параметры метода. Таким образом, в C # foo будет выделено в стеке:

public function bar() { 
    int foo = 2;
    ...
}

В качестве альтернативы, динамически распределяемые переменные используют память из кучи. Это должно иметь интуитивно понятный смысл, так как в противном случае стек должен был бы динамически расти каждый раз, когда вызывается new. Кроме того, это будет означать, что такие переменные могут использоваться только в качестве локальных в локальной функции, которая их выделяет, что, конечно, неверно, поскольку мы можем иметь (например) переменные-члены класса. Итак, чтобы взять другой пример из C #, в следующем случае result выделяется в куче:

public class MyInt
{         
    public int MyValue;
}

...
MyInt result = new MyInt();
result.MyValue = foo + 40;
...

Теперь, имея в виду этот фон, память в куче 1015 * собирается мусором. Память в стеке не нуждается в GC, так как память будет возвращена, когда текущая функция вернется. На высоком уровне алгоритм GC работает, отслеживая все объекты, которые динамически размещаются в куче. После выделения через new объект будет отслеживаться GC и собираться, когда он больше не находится в области видимости и на него больше нет ссылок.

2 голосов
/ 28 февраля 2010

Во-первых, как распределяются данные? т.е. в стеке или куче (согласно моему знание, все статическое или глобальное переменным назначается место в стеке и локальным переменным назначается пространство в куче).

Нет, переменные стека - это вызовы методов и локальные переменные. Фрейм стека создается при вызове метода и извлекается при его возврате.

Память в Java и C # выделяется в куче с помощью вызова «new».

Во-вторых, GC работает с данными в стеках или кучи? т.е. алгоритм GC, как Mark / Sweep будет ссылаться на данные о стек как корень установлен правильно? А потом карта все достижимые переменные в куче проверка, какие переменные в куче относятся в корневой набор.

GC используется в куче.

Метка и развертка не будут считаться передовым алгоритмом GC. И Java, и .NET GC теперь используют модели поколений.

Что делать, если программа не имеет глобальная переменная? Как работает алгоритм работает тогда?

Что означает «глобальная переменная» в таких языках, как Java и C #, где все принадлежит классу?

Корень графа объекта является произвольным. Я признаю, что я не знаю, как он выбран.

2 голосов
/ 28 февраля 2010
1 голос
/ 01 марта 2010

Ричард и Карл получили отличное представление о модели памяти Windows, включая модель .NET и GC, в своих .NET Rocks! архивы:

Джеффри Рихтер о модели памяти Windows

1 голос
/ 01 марта 2010

Читать эту статью . Это очень хороший обзор однопроцессорных методов сбора мусора. Это даст вам базовое понимание и терминологию по GC. Затем ознакомьтесь с книгой Джонса и Линса «Сборка мусора: алгоритмы автоматического динамического управления памятью». В отличие от статьи, на которую я указал выше, книга не доступна бесплатно в Интернете; Вы должны купить это; но оно того стоит.

0 голосов
/ 14 июля 2011

Вы можете найти краткую сводку Сборка мусора в Справочнике по управлению памятью полезной.

В конечном итоге сборка мусора должна начинаться с регистров процессора (ов), поскольку любые объекты, которые не могут быть получены процессором, могут быть переработаны. В зависимости от языка и системы времени выполнения имеет смысл предположить статически, что стеки и регистры потоков также доступны, как и «глобальные переменные».

Стеки, вероятно, получают локальные переменные. Таким образом, в простых GC вы начинаете со сканирования контекстов потоков, их стеков и глобальных переменных. Но это, конечно, не так в каждом случае. Некоторые языки не используют стеки или имеют глобальные переменные как таковые. Более того, GC могут использовать барьер , чтобы им не приходилось каждый раз смотреть на каждый стек или глобал. Некоторые специализированные аппаратные средства, такие как Symbolics Lisp Machine , имели барьеры на регистрах!

...