Сборка мусора - потерянные ссылки LinkedList - PullRequest
12 голосов
/ 04 августа 2011

Предположим, у вас есть ссылки A -> B -> C -> D.Когда вы удаляете ссылку на B из A, вы остаетесь с потерянной цепочкой объектов B -> C -> D.

Будет ли C и D собираться мусором, даже если нет никакого способачтобы получить к ним (так как нет ссылки на B)?

Я думаю, что GC умен в этом и разрешит любые такие зависимости.

Однако я взглянул на Исходный код для класса LinkedList и нашел что-то противоречащее этому убеждению.Я заметил, что когда список clear() ed, все ссылки на каждую ссылку явно устанавливаются на null, что делает его операцией O(n).Есть ли какая-либо причина / польза для этого?

Ответы [ 2 ]

11 голосов
/ 04 августа 2011

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

Конечно, это НЕ сделано, чтобы ускорить сборку мусора. Сборщик мусора не пересекает ссылки в недоступном объекте, поэтому обнуление их не будет иметь никакого значения.

UPDATE

Более поздняя версия метода имеет следующие комментарии:

// Clearing all of the links between nodes is "unnecessary", but:
// - helps a generational GC if the discarded nodes inhabit
//   more than one generation
// - is sure to free memory even if there is a reachable Iterator

Итак, похоже, что у GC есть польза, по крайней мере, в некоторых случаях.

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

Если вы обойдете список и разберете его, переменной, содержащей старую -> новую ссылку, присваивается значение null. Барьер записи для этого назначения приводит к тому, что (немедленно или во время GC) исходная ссылка больше не является «корнем». Таким образом, объект в младшем поколении теперь можно собирать, и он не в конечном итоге «завладевает» старшему поколению (что продвигает время, когда необходимо собрать это поколение).

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

Для получения дополнительной информации см. «Алгоритмы сбора мусора для динамического управления памятью» Джонс и Линс. Он находится в главе 7.5 в моем (первом издании) экземпляре.


Вообще говоря, лучше выбросить Collection объект и начать заново, чем очистить его для повторного использования.

2 голосов
/ 04 августа 2011

Да, C и D будут собирать мусор, предполагая, что B является единственной ссылкой на них.Это связано с тем, что они не достижимы от графа до корневых объектов графа объекта приложения.

Я предполагаю, что причина пометки каждой ссылки на null в реализации LinkedList заключается в предотвращении утечки памяти,Для чего-то за пределами LinkedList возможно захватить головной узел.Если бы это произошло, все остальные узлы остались бы живыми даже после очистки LinkedList.

...