Какое примерное количество горутин можно запустить на компьютере с 16 ГБ оперативной памяти?
Что проверяют
Умеете ли вы оценить стоимость горутины и понимаете ли, что упрётесь не в память. Интервьюер ждёт порядок величины с расчётом, а затем разговор о том, что реально ограничивает систему. Следом обычно спрашивают, как ограничить число одновременных горутин и как найти утечку.
Как отвечать
Посчитайте вслух. Стартовый стек горутины 2 КБ, плюс служебная структура g в несколько сотен байт, итого от 2,5 до 3 КБ на спящую горутину. 16 ГБ делим на 2,5 КБ и получаем порядка 6 миллионов. Синтетический тест с горутинами, которые просто ждут на канале, такой порядок и показывает.
Затем поправки:
- стек растёт: он динамический, при нехватке рантайм выделяет вдвое больший и копирует. Горутина с глубокими вызовами легко занимает десятки килобайт, а с Go 1.19 стартовый размер ещё и подстраивается под средний расход;
- данные горутины: буферы, структуры запроса, соединения лежат в куче и обычно весят больше стека;
- ОС и GC: память нужна самому процессу, ядру и сборщику мусора, которому при большой куче нужен запас;
- потоки ОС: горутина, заблокированная в системном вызове или cgo, держит поток. Лимит потоков по умолчанию 10 000 (
debug.SetMaxThreads), при превышении программа падает; - внешние ресурсы: файловые дескрипторы (
ulimit -n), соединения с базой, лимиты сервиса, в который вы ходите.
Реалистичный ответ: сотни тысяч рабочих горутин на такой машине нормально, миллионы возможны для простаивающих. Одновременно выполняется не больше GOMAXPROCS, остальные ждут. Поэтому число горутин ограничивают осознанно: пул воркеров, семафор на буферизованном канале, errgroup с SetLimit. Контролируют через runtime.NumGoroutine() и профиль goroutine в pprof.
Где спотыкаются
Ошибаются в единицах: делят 16 384 МБ на 2 КБ, не переведя в одни единицы, и получают 8 тысяч вместо примерно 8 миллионов.
Путают GOMAXPROCS с лимитом горутин. Он ограничивает число потоков, одновременно выполняющих Go-код, а не количество горутин.
Не думают об утечках. Горутина, навсегда заблокированная на канале без читателя, не освобождается, и сервис медленно съедает память, пока не упадёт по OOM.