Несколько указателей и Mark & ​​Sweep - PullRequest
2 голосов
/ 09 марта 2019

Я пытаюсь реализовать небольшой язык сценариев и собираюсь решить, какой алгоритм сборки мусора соответствует моим преимуществам. Я выбрал Mark & ​​Sweep, но, думаю, неправильно понял концепцию.

Допустим, вызывается произвольная функция, и она создает следующие переменные (возможно, они не имеют имен, но для простоты предположим, что они созданы в этой функции).

f() {
    /*f creates following variables*/     
    x = (1,2,(3,4,(5,6))); //this is tuple
    a = x;
    y = x[2];
    z = y[2];
    p = (10,y);
}

В приведенном выше примере все является объектом (целые числа, строки, кортежи, двойные числа и т. Д.), А кортежи содержат указатели на его объекты. Более того, каждый объект живет в куче. Когда функция выходит из области видимости, она должна удалить выделенные переменные. Область действия функции выглядит следующим образом.

+-----+
|     |
|  x  +---------->(1,2,+)
+-----+           ^    |
                  |    v
+-----+           |    (3,4,+)
|     |           |    ^    |
|  a  +-----------+    |    v
+-----+                |    (5,6)
                       |    ^
+-----+                |    |
|     |                |    |
|  y  +----------------+    |
+-----+                |    |
                       |    |
+-----+                |    |
|     |                |    |
|  z  +---------------------+
+-----+                |
                       |
+-----+                |
|     |                |
|  p  +----------->(10,+)
+-----+

Все переменные (a, x, y, z, p) должны быть удалены, но вопрос в том, как? Я знаю, что Mark & ​​Sweep - это алгоритм сборки мусора, и я подумал, что эти переменные теперь мой мусор. Функция завершила свою работу и должна вернуть выделенную память системе.

Я попробовал следующее, каждый объект содержит бит метки, и после создания бит метки устанавливается в 0. Когда программа помещает объект, удерживаемый переменной, она конвертирует свою метку в 1, и не возникает свободных ошибок, потому что все в Программа знает, что у нее есть владелец. Пока все хорошо, этот подход сработал. Но если у меня много переменных, как в примере, как я могу удалить несколько указателей?

Здесь я предположил, что сначала нужно разорвать владение между x и его объектом. Затем произнесите каждую переменную, чтобы пометить свои объекты (и если объект является кортежем, то он устанавливает рекурсивный бит меток для своих объектов в 1). Теперь (1,2, ...) бит метки объекта устанавливается в 1 переменной 'a'; Я могу попытаться освободить его, но программа не позволяет. Если я сделаю это для каждой переменной в моей таблице, сложность будет выглядеть огромной (у меня есть метка и фаза развертки для каждого объекта).

У меня вопрос, я прав насчет алгоритма Mark & ​​Sweep? Корни мои переменные? Как я могу удалить несколько указателей и даже циклические ссылки?

1 Ответ

1 голос
/ 09 марта 2019

Для Mark and Sweep вам необходимо иметь возможность сканировать все выделенные объекты на одной стороне и все достижимые объекты на другой.

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

  • После того, как все достижимые объекты были отмечены, отсканируйте все выделенные объекты: для каждого объекта, если он отмечен, снимите отметку, в противном случае он недоступен, поэтому соберите его (т. Е. Сделайте его доступным для перераспределения или освобождения это).

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

Когда вы меняете ссылки на объекты в ходе обычной работы программ, вам не нужно делать ничего особенного: просто сохраните адрес новой ссылки.

Чтобы эффективно удалить объекты, на которые ссылаются ваши глобальные переменные, вы просто должны сделать так, чтобы эти переменные указывали на null или какой-либо другой объект.

Преимущества Mark & ​​Sweep - это относительная простота алгоритма и возможность собирать сложные структуры с циклами. Недостатком является время, затрачиваемое на режим остановки мира , особенно в многопоточных приложениях и приложениях реального времени или даже интерактивных пользователях. Были найдены более продвинутые методы для решения этих проблем, но их реализация может быть очень сложной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...