ется до тех пор, пока не будут перебраны все объекты серого множества. Затем объекты белого множества считаются недостижимыми, и занимаемая ими память может использоваться повторно. Таким образом, считается, что в этот момент элементы белого множества попали в корзину.
Обратите внимание: если в какой-то момент сборки мусора объект из серого множества станет недостижимым, он будет обработан не в этом, а в следующем цикле сборки мусора! Это не оптимальный, но и не такой уж плохой вариант.
Приложение, работающее во время выполнения сборки мусора, называется мутатором. Мутатор запускает небольшую функцию, называемую барьером записи. Эта функция выполняется всякий раз, когда изменяется указатель в куче. Если указатель объекта в куче изменился, это означает, что данный объект теперь достижим. Барьер записи помечает этот объект в серый цвет и помещает в серое множество.
Мутатор отвечает за то, чтобы ни один элемент из черного множества не имел указателя на элемент из белого множества. Это достигается с помощью функции барьера записи. Невыполнение этого условия разрушило бы процесс сборки мусора и, скорее всего, привело бы к аварийному завершению работы программы.
В итоге кучу можно представить как граф, состоящий из связанных объектов. Такой граф показан на рис. 2.1, где также продемонстрирован один из этапов сборки мусора.
Рис. 2.1. В Go при сборке мусора в корзину область кучи программы можно представить в виде графа
Итак, у нас есть три цвета: черный, белый и серый. Когда алгоритм начинает работу, все объекты окрашены в белый цвет. По мере работы алгоритма белые объекты перемещаются в одно из двух остальных множеств: серое или черное. Те объекты, которые останутся в белом множестве, в какой-то момент будут удалены.
На представленном графе видно, что, хотя объект E, который относится к белому множеству, может получить доступ к объекту F, он сам недостижим из какого-либо другого объекта, потому что никакой другой объект не указывает на объект E. Это делает объект E идеальным