Перейти к потреблению памяти со многими горутинами

Я пытался проверить, как Go будет работать с 100 000 горутин. Я написал простую программу для порождения такого количества подпрограмм, которые ничего не делают, кроме вывода объявлений. Я ограничил размер MaxStack всего 512 байтами. Но я заметил, что размер программы при этом не уменьшается. Он потреблял около 460 МБ памяти и, следовательно, около 4 КБ на горутину. Мой вопрос: можем ли мы установить максимальный размер стека ниже «минимального» размера стека (который может составлять 4 КБ) для горутин. Как мы можем установить минимальный размер стека, с которого начинается Горутина? Ниже приведен пример кода, который я использовал для теста:

package main

import "fmt"
import "time"

import "runtime/debug"

func main() {
    fmt.Printf("%v\n", debug.SetMaxStack(512))
    var i int
    for i = 0; i < 100000; i++ {
        go func(x int) {
            for {
                time.Sleep(10 * time.Millisecond)
                //fmt.Printf("I am %v\n", x)
            }
        }(i)
    }
    fmt.Println("Done")
    time.Sleep(999999999999)
}

person Nipun Talukdar    schedule 11.03.2014    source источник


Ответы (3)


Функция runtime/debug.SetMaxStack только определяет, в какой момент программа считается бесконечно рекурсивной, и завершает ее. http://golang.org/pkg/runtime/debug/#SetMaxStack

Установка абсурдно низкого значения никак не влияет на минимальный размер стеков и ограничивает только максимальный размер из-за сбоя вашей программы, когда размер любого используемого стека превышает предел.

Технически сбой происходит только тогда, когда стек должен быть увеличен, поэтому ваша программа умрет, когда стеку потребуется более 8 КБ (или 4 КБ до перехода на 1.2).

Причина, по которой ваша программа использует минимум 4 КБ * nGoroutines, заключается в том, что стеки выровнены по страницам, поэтому на странице виртуальной машины никогда не может быть более одного стека. Поэтому ваша программа будет использовать как минимум nGoroutines страниц, а операционные системы обычно измеряют и распределяют память только с шагом в размер страницы.

Единственный способ изменить начальный (минимальный) размер стека — изменить и перекомпилировать среду выполнения go (и, возможно, компилятор тоже).

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

person Cookie of Nine    schedule 11.03.2014
comment
Go 1.3 будет иметь минимальный размер стека на уровне 4 КБ. Мы надеемся, что Go 1.4 сможет уменьшить минимальный размер стека до 1 или 2 КБ. - person Russ Cox; 12.03.2014

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

Go 1.2 увеличил минимальный размер с 4 КБ до 8 КБ.

Документы говорят:

«В Go 1.2 минимальный размер стека при создании горутины был увеличен с 4 КБ до 8 КБ. Многие программы страдали от проблем с производительностью из-за старого размера, что имело тенденцию вводить дорогостоящее переключение сегментов стека в критически важных для производительности приложениях. разделов. Новое число было определено эмпирическим тестированием».

Но они продолжают говорить:

«Обновление: увеличенный минимальный размер стека может привести к тому, что программы с большим количеством горутин будут использовать больше памяти. Обходного пути нет, но планы на будущие выпуски включают новую технологию управления стеком, которая должна лучше решать проблему».

Так что в будущем вам может повезти.

Дополнительную информацию см. на странице http://golang.org/doc/go1.2#stack_size.

person Intermernet    schedule 11.03.2014
comment
Я использую Go 1.2.1 в Windows. Я предполагаю, что минимальный размер стека по-прежнему составляет 4 КБ, так как процесс со 100 000 горутин потребляет около 460 МБ. - person Nipun Talukdar; 11.03.2014
comment
В большинстве систем вторая страница размером 4 КБ не загружается до тех пор, пока она не понадобится стеку. Я не уверен, что такое терминология в Windows, но вы, вероятно, используете в два раза больше виртуальной памяти, чем это. - person JimB; 11.03.2014

Просто примечание: в Go 1.4 минимальный размер стека горутин уменьшился с 8 КБ до 2 КБ.

И согласно Go 1.13, это все равно - https://github.com/golang/go/blob/bbd25d26c0a86660fb3968137f16e74837b7a9c6/src/runtime/stack.go#L72:

// The minimum size of stack used by Go code
_StackMin = 2048
person Vilen Topchii    schedule 31.12.2019