Fernando Simões в разборе эксперимента показал, как swap, область на диске для выгрузки страниц памяти, задержал программу на Go в тесте на Linux 6.8. Медианная пауза сборщика мусора, механизма освобождения ненужной памяти, составила около 51 мкс, а худшая при хранении его служебных данных на диске — 40 мс.

Причиной стала загрузка служебных данных сборщика с диска в момент, когда Go приостанавливал выполнение программы. В худшем замере 39 из 40 мс ушли на обработку 228 обращений к отсутствующим в оперативной памяти страницам.

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

Проверка утверждений:

  • Fernando Simões описал эксперимент на Linux 6.8, в котором чтение выгруженных в swap служебных данных сборщика мусора Go увеличило худшую паузу до 40 мс. (подтверждено самой публикацией: доказательство; «I was wrong. While experimenting with this, I found a problem that could’ve hurt me: Go’s garbage collector reads its metadata (outside the heap, in a region that is not freed ) in a stop-the-world pause, and that metadata can be in swap. I did a mock run on a Hetzner box using kernel 6.8 with MGLRU enabled 1 1 You can find everything about these experiments: plots, the mock allocator, bpf scripts, python scripts, etc., here: https://github.com/frnsimoes/go-gc-swap-cost . The median pause was around 51 us. With the metadata on the NVMe, the worst pause was 40ms.»)
  • В эксперименте медианная пауза сборщика мусора Go составила около 51 мкс. (подтверждено самой публикацией: доказательство; «The median pause was around 51 us.»)
  • В худшем замере 39 из 40 мс ушли на обработку 228 обращений к отсутствующим в оперативной памяти страницам. (подтверждено самой публикацией: доказательство; «This was the worst one: 39902 us, faults during it 228, 39013 us in faults . 39 of those 40ms were spent in 228 page faults.»)
  • На время такой паузы останавливается вся программа на Go, поэтому она не может обработать даже уже завершившийся ввод-вывод. (подтверждено самой публикацией: доказательство; «Those 40ms mean everything has stopped - in Go’s terminology, every P has stopped , so, for example, if a goroutine was waiting for I/O, during that pause the I/O might return and there would be no one to handle it.»)

Первоисточники:

оценка 51,3 из 100 · тип: руководство