Будет ли b когда-либо иметь право на сборку мусора (до завершения DoSomeLongWork)?
Потенциально да, при условии, что a
и b
исключены компилятором из набора глобальных корней (то есть не хранятся в стеке), после чего они могут быть восстановлены коллекцией в течение DoSomeLongWork
.
Я обнаружил случаи, когда .NET восстанавливает, но моно пропускает память .
Ссылка на b, содержащаяся в classList, может ли она считаться корнем?
Будет ли b
превращен в глобальный корень, полностью зависит от компилятора.
Игрушечный компилятор может выдвигать ссылки из аргументов функций и возвращаться из вызовов функций в стек и разматывать стек в конце каждой функции. В этом случае b
будет помещено в стек и, следовательно, будет глобальным корнем.
Компиляторы качества производства выполняют сложное распределение регистров и поддерживают только действующие ссылки в стеке, перезаписывая или обнуляя ссылки в стеке по мере их смерти. В этом случае b
не работает во время вызова DoSomeLongWork
, поэтому его запись в стеке будет обнуляться или перезаписываться.
Ничто из этого не может быть выведено из исходного кода без подробных сведений о том, что именно будет делать компилятор. Например, мой проект HLVM на данном этапе является всего лишь игрушкой, использующей прежнюю технику, но в данном случае он фактически соберет a
и b
, поскольку вызов DoSomeLongWork
является хвостом. звоните.
Или корень - это только первая ссылка на экземпляр?
Глобальные корни - это ссылки, с которых начинается GC для прохождения всех доступных данных в куче. Глобальные корни обычно представляют собой глобальные переменные и стеки потоков, но более сложные алгоритмы GC могут вводить новые виды глобальных корней, например, запоминающиеся наборы.