Очистка двусвязного списка

У меня есть двойной связанный список (очередь), который я сделал самостоятельно.

Мне интересно, чтобы очистить связанный список, достаточно ли просто удалить ссылки на начало и конец?

E.g

public void Clear()
{
    Head = null;
    Tail = null;
}

Я представляю себе эффект домино, но мне трудно его протестировать. По крайней мере, это сделает весь объект пустым. Все запросы данных (такие как peek, dequeue и т. д.) возвращают значение null. Вы также можете легко поставить в очередь некоторые новые объекты. Чисто функционально вроде работает.

Но мне очень хотелось бы знать, правильно ли я поступаю.


person CasperT    schedule 16.10.2009    source источник


Ответы (3)


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

Самый простой способ протестировать — добавить финализатор к объекту узла связанного списка, который выводит некоторые журналы. Обратите внимание, что вы не можете быть уверены, когда запустится сборщик мусора (без форсирования, через GC.Collect()), поэтому вы не увидите вызываемый финализатор, как только вы вызовете метод Clear().

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

person FacticiusVir    schedule 16.10.2009
comment
Спасибо, хорошо объясняете - person CasperT; 16.10.2009

Если объекты в коллекции не должны быть утилизированы, и за это отвечает коллекция, то ваш метод, вероятно, является лучшим способом.

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

person Lasse V. Karlsen    schedule 16.10.2009
comment
Вопрос в том, произойдет ли это за один проход GC, или каждая «строка» в эффекте домино, как описывает OP, займет один проход? - person Matthew Scharley; 16.10.2009
comment
Спасибо за ответ. Это вселяло уверенность. Я приму FacticiusVir, потому что он более подробно объяснил, что произойдет :) - person CasperT; 16.10.2009
comment
Это произойдет за один проход. Сборка мусора не удаляет только объекты без активных ссылок на них, а пытается отследить ссылки до того, что известно как корни, в основном такие вещи, как статические переменные, локальные переменные в все еще работающих методах и т. д. Если длинная цепочка объектов не имеет такой корневой ссылки, вся цепочка может быть собрана за один и тот же проход. - person Lasse V. Karlsen; 16.10.2009

Я представляю эффект домино

Это не то, как работает GC.

Сборщик мусора сначала помечает все как «мертвое», затем, начиная с корневых объектов, он обходит все объекты, на которые они ссылаются, помечая каждый из них как «живой».

Поскольку на ваш список больше не ссылаются какие-либо корневые объекты (или их дочерние элементы), он будет помечен как «мертвый».

Затем второй проход освобождает «мертвые» объекты.

Я сомневаюсь, что вы можете предположить в финализаторе, что какие-либо объекты по обе стороны списка не были собраны первыми, т.е. они будут в порядке GC, а не в порядке списка.

Немного подробнее здесь: - http://msdn.microsoft.com/en-us/magazine/bb985010.aspx

person Community    schedule 16.10.2009