Есть ли спецификация для модели времени жизни Go выделенной памяти? - PullRequest
0 голосов
/ 29 апреля 2020

Go использует Escape-анализ и сборку мусора для управления распределением памяти в стеке и куче. Go FAQ также говорит:

Как узнать, размещена ли переменная в куче или стеке?

С точки зрения правильности вам не нужно знать. Каждая переменная в Go существует, пока есть ссылки на нее. Место хранения, выбранное реализацией, не имеет отношения к семантике языка.

Поэтому Go выделяет память для переменной и резервирует ее по крайней мере до тех пор, пока она не понадобится.

Мой вопрос: написано ли это (абстрактное) поведение в Go Спецификации языка программирования ? Я обнаружил, что часть выделения написана, например, в Раздел выделения :

Встроенная функция new принимает тип T, выделяет память для переменной этого типа во время выполнения, и возвращает значение типа *T, указывающее на него.

Но есть ли описание части резервирования? Можем ли мы подтвердить факт «Каждая переменная в Go существует, пока есть ссылки на нее»? Если нет, то есть ли причины?

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

func foo() *int {
    x := 42
    return &x
}
func main() {
    px := foo()
    fmt.Println(*px)
}

Чтобы быть более точным, я ожидал, что две части, «Go выделяет память, когда new или что-то в этом роде» и «Go резервирует выделенную память, по крайней мере, для нее необходимо», должны быть записаны в спецификации. Меня не волнуют детали его реализации, хотя https://github.com/golang/go использует Escape-анализ и сборку мусора.

Если последняя часть не существует, то в крайнем случае она действительна реализация согласно спецификации c, что память не выделяется сразу после ее выделения. Но это смешно, поэтому я думаю, что spe c должен сделать это недействительным.

Редактировать для закрытия: я не думаю, что этот вопрос основан на мнении. Этот вопрос является простым вопросом да / нет, спрашивая описание в спецификации. Причину существования / несуществования можно ответить цитатами. Если нет, пожалуйста, покажите / прокомментируйте, какие пункты основаны на мнении. Я улучшу это.

Ответы [ 3 ]

1 голос
/ 03 мая 2020

В спецификации используется термин переменная для места хранения. Спецификация не различает guish между хранилищами в куче или стеке. Термины куча и стек отсутствуют в спецификации.

Раздел для переменных говорит:

A значение переменной извлекается путем обращения к переменной в выражении; это самое последнее значение, присвоенное переменной. Если переменной еще не было присвоено значение, ее значение является нулевым значением для ее типа.

Если на переменную можно ссылаться, то значение переменной можно извлечь. Компилятор и среда выполнения должны сохранять значение переменной при наличии существующих ссылок на переменную.

0 голосов
/ 29 апреля 2020

То, что вы можете себе представить, может вызвать проблему, это *px в основной функции. Если вещь, на которую указывает px, больше не существует. Однако, согласно этому разделу: https://golang.org/ref/spec#Address_operators

Для операнда x типа указателя * T, косвенное указатель * x обозначает переменную типа T, на которую указывает x , Если x равен нулю, попытка оценить * x вызовет пани во время выполнения c.

Это в основном говорит о том, что реализация Go обязательно даст вам указанное значение, если указатель не равен nil, в этом случае он будет pani c. В спецификации не сказано, как реализация должна это делать, но вы можете рассчитывать на любую реализацию Go, которая делает это каким-то образом.

Это соответствует тому, что говорится в вашей первой цитате.

0 голосов
/ 29 апреля 2020

Но есть ли описание консервационной части? Можем ли мы подтвердить факт «Каждая переменная в Go существует, пока есть ссылки на нее»? Если нет, есть ли причины?

Нет в спецификации языка, нет; это качество среды выполнения, а не языка. Мы можем подтвердить тот факт, что память не собирается, если есть ссылки на нее, просто наблюдая, что Go программы действительно работают. Если бы это предположение было неверным, большая часть стандартной библиотеки была бы недействительной вместе с почти всем кодом, написанным любым Go разработчиком. Анализ побега компилятора Go и сборщик мусора определенно работают.

Найденная вами запись часто задаваемых вопросов является канонической и на нее можно положиться, так же как и в случае с c.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...