2013-08-23 2 views
2

Будет сборщик мусора (теоретически) собрать такую ​​структуру?Сбор мусора/связанный список

package main 

type node struct { 
    next *node 
    prev *node 
} 

func (a *node) append(b *node) { 
    a.next = b 
    b.prev = a 
} 

func main() { 
    a := new(node) 
    b := new(node) 
    a.append(b) 
    b = nil 
    a = nil 
} 

Это должен быть связанный список. a указывает на b, b указывает на a. Когда я удаляю ссылку в a и b (последние две строки), эти два узла больше не доступны. Но у каждого узла есть ссылка. Будет ли сборщик мусора убирать эти узлы тем не менее?

(Очевидно, что не в коде выше, а в более длительной программе).

Есть ли какая-либо документация по сборщику мусора, которая обрабатывает эти вопросы?

ответ

4

Набор сборщиков мусора (GC) в вашей программе - {a, b}. Установка всех из них на nil делает все содержимое кучи пригодным для сбора, потому что теперь все существующие узлы, даже если они имеют значение, не являются достижимыми из любого корня.

Тот же принцип гарантирует также, например, что структуры с циркулярными и/или собственными ссылками собираются, когда они становятся недоступными.

+0

Спасибо! Я постараюсь узнать больше о GC в целом и Go's GC в специальном. Вы случайно знаете какую-либо документацию сборщика мусора Go? – topskip

+0

@topskip: К сожалению, я не знаю о такой документации. Раньше это был консервативный GC, в настоящее время он в основном является точным GC с небольшим количеством оставшихся мест (я думаю, что записи о вызовах [стоковые кадры] еще не точны). – zzzz

2

Опасность, которую вы описываете, на самом деле представляет собой реальную проблему с простой, но малоиспользуемой схемой сбора мусора, известной как «подсчет ссылок». По сути, именно так, как вы подразумеваете, сборщик мусора (GC) подсчитывает, сколько ссылок существует для данного объекта, а когда это число достигает 0, это GC'd. И, действительно, круговые ссылки будут препятствовать тому, чтобы эталонная система подсчета получала от GC-ing эту структуру.

Вместо этого многие современные GC (в том числе Go, см. this post) - это процесс, известный как mark-and-sweep. По существу, все ссылки верхнего уровня (указатели, которые у вас есть в области некоторой функции) отмечены как «достижимые», а затем все ссылки, на которые ссылаются ссылки, помечены как достижимые и т. Д., Пока не будут отмечены все доступные объекты , Тогда все, что не было отмечено, как известно, недостижимо и является GC'd. Циркулярные ссылки не являются проблемой, потому что, если они не ссылаются на верхний уровень, они не будут отмечены.

+0

Спасибо за отличное объяснение (+ ссылки)! – topskip

+0

Да, проблем нет! – joshlf

Смежные вопросы