Ответ 1
TL;DR:
- Вы не можете использовать ТБ ОЗУ с одним процессом Go прямо сейчас. Max - 512 ГБ на Linux, и большинство из тех, что я видел, протестировано - 240 ГБ.
- С текущим фоном GC рабочая нагрузка GC имеет тенденцию быть более важной, чем паузы GC.
- Вы можете понять рабочую нагрузку GC как указатель * скорость распределения/запасную RAM. Из приложений, использующих тонны ОЗУ, только те, у кого мало указателей или небольшое распределение, будут иметь небольшую рабочую нагрузку на GC.
Я согласен с комментарием, что огромные кучи заслуживают внимания других людей (или тестирования). JimB отмечает, что Go heaps имеют жесткий лимит в 512 ГБ прямо сейчас, а 18 240 ГБ - это то, что я видел.
Некоторые вещи, которые мы знаем о огромных кучах, от проектный документ и слайды GopherCon 2015:
- Коллекционер 1.5 не стремится к сокращению работы GC, просто сокращает паузы, работая в фоновом режиме.
- Ваш код приостанавливается, пока GC сканирует указатели на стек и глобальные переменные.
-
1.5 GC имеет короткую паузу на контрольном контроле GC с грубой массой 18 ГБ, как показано самой правой желтой точкой внизу этот график из беседы GopherCon:
Люди, работающие с несколькими производственными приложениями, у которых в начале было около 300 мсек пауз, сообщили о снижении до ~ 4ms и ~ 20 мс. Другое приложение сообщило, что их 95-е процентильное время GC прошло от от 279 мс до ~ 10 мс.
Go 1.6 добавил полис и переместил часть оставшейся работы на задний план. В результате тесты с кучами до бит более 200 ГБ по-прежнему видели максимальное время паузы в 20 мс, как показано в слайд в начале 2016 Обсуждение состояния:
То же приложение, у которого время паузы в 20 мсек. меньше 1,5, 3-4ms приостанавливается до 1,6, причем около 8 ГБ кучи и 150 М выделений/минута.
Twitch, который использует Go для своего чата, сообщил, что by 1.7 время паузы сократилось до 1 мс с большим количеством запущенных goroutines,
1.8 выполнил сканирование стека из фазы "стоп-мир" , в результате чего большинство пауз значительно сократилось до 1 мс даже на больших кучах. Ранние номера выглядят хорошо. Иногда приложения все еще имеют шаблоны кода, из-за которых goroutine трудно приостановить, эффективно удлиняя паузу для всех других потоков, но, как правило, справедливо утверждать, что работа с фоновой музыкой GC теперь намного важнее, чем паузы GC.
Некоторые общие наблюдения за сбором мусора, не относящиеся к Go:
- Частота коллекций зависит от того, насколько быстро вы используете RAM, который вы готовы предоставить процессу.
- Объем работы каждой коллекции зависит от того, сколько указателей используется. (Который включает указатели в срезах, значениях интерфейса, строках и т.д.)
Перефразированное приложение, обращающееся к большому объему памяти, может все еще не иметь проблемы с GC, если у него есть только несколько указателей (например, он обрабатывает относительно немного больших буферов []byte
), а коллекции случаются реже, если скорость распределения низкая (например, потому что вы применили sync.Pool
для повторного использования памяти, где бы вы быстрее пережевывали RAM).
Итак, если вы смотрите на что-то, включающее кучи сотен ГБ, которые не являются естественными для GC, я бы предложил вам рассмотреть любой из
- запись на C или такая
- перемещение громоздких данных из графа объектов. Например, вы можете управлять данными во встроенной базе данных, например
bolt
, поместить ее во внешнюю службу БД или использовать что-то вродеgroupcache
или memcache, если вы хотите больше кеша, чем DB - выполняется набор процессов с меньшим объемом, а не один большой
- просто тщательно прототипируйте, тестируйте и оптимизируйте, чтобы избежать проблем с памятью.