· kaynak Hacker News – Front Page (native)
Swap, Go GC metaverisini diske iterek 40ms'lik stop-the-world duraklamalarına yol açtı
Bir geliştiricinin swap deneyimi, tipik olarak 51 mikrosaniye süren Go GC duraklamalarını 40ms'lik stop-the-world duraklamalarına dönüştürdü; suçlu ise toplayıcının metaverisi üzerindeki page fault'lar

Swap bir latency bütçesini nasıl bozdu
Bellek ani yükselişlerini absorbe etmek için üretimde swap'ı etkinleştiren bir geliştirici, bu kararın bir Go servisinde 40ms'lik stop-the-world duraklamalarına — normal duraklamanın yaklaşık 800 katı — nasıl yol açtığını belgeledi. Hacker News'in ana sayfasına ulaşan frn.sh üzerindeki teknik yazıda yazar, duraklamaların kaynağını çöp toplayıcının kendi defter tutma verileri üzerindeki page fault'lara bağlıyor.
Test ortamı iki süreç barındıran bir cgroup'tan oluşuyordu: io.ReadAll ile veri okuyan ve proto.Unmarshal ile çözümleyen, ayrıca allocator'ın işaretçi içerdiğini belirttiği bir blob ve bir grafik yapısı inşa eden bir Go programı ile çoğunlukla boşta duran bir HTTP sunucusu.
Yazar bu etkileşimin zararsız olmasını bekliyordu. Çekirdek sayfaları süreç başına değil cgroup başına hesaplayıp tahliye ettiğinden, reclaim baskısının iki sürecin belleğine de yayılması ve toplayıcının kendi sayfalarının özellikle hedef alınma olasılığının düşük olması gerekiyordu. Testler bu akıl yürütmeyi yanlışladı.
Heap'in dışındaki metaveri
Yazının merkezindeki bulgu şuydu: Go'nun toplayıcısı metaverisini stop-the-world duraklamaları sırasında okur ve bu metaveri, runtime'ın bir kez ayırıp yeniden kullandığı ve asla serbest bırakmadığı, heap'in dışındaki sayfalarda yaşar. Çekirdeğin bu sayfaları tahliye etmesini engelleyen bir şey yoktur.
Reclaim en son kullanılan sayfaları hedef aldığından ve GC defter tutma verilerine yalnızca döngüler arasındaki patlamalar halinde dokunduğundan, bu sayfalar yaşlanıp dışarı atılır. Toplayıcı bir sonaki seferde dünyayı durdurup bunları okuduğunda major page fault tetiklenir: çekirdek page table'ları gezinir, do_swap_page'i çağırır, yeni bir çerçeve bulur ve hesaba katar, I/O gönderir ve diski bekler — bu sırada tüm Go scheduler slotları durmuş halde bekler.
Rakamlar
MGLRU etkin, 6.8 çekirdekli bir Hetzner makinesinde medyan duraklama yaklaşık 51 mikrosaniye ölçüldü. Metaveri yerel NVMe'ye sayfalandığında ise en kötü duraklama 40ms'ye ulaştı.
Dünya dururken page fault'ları sayan bir BPF betiği farkı açıkladı: 39.902 mikrosaniyelik en kötü duraklama, 228 page fault içinde 39.013 mikrosaniye geçirmişti; stack trace'ler spanSet.reset, finishsweep_m, nextMarkBitArenaEpoch ve gcStart gibi GC defter tutma noktalarına düşüyordu. Go, dünya süpürme sonlandırması ve işaretleme sonlandırmasında durdurur; 30 dakikalık çalışma 312 böyle duraklama kaydetti ve en kötü duraklamalar her bellek ani yükselişinde iki ila üç kez görüldü.
İkinci, yerelleştirilmiş bir maliyet
Ayrı olarak, normalde 3-5ms süren tek bir 511 KiB'lik mesajı oluşturmak, veri NVMe üzerindeyken 105ms, Hetzner'in ağ destekli volume'unda ise 903ms sürdü. Mesaj başına bu, metaveri duraklama maliyetini aşıyor; ancak bunu tüm süreç değil yalnızca ayırma yapan goroutine ödüyor. Yazar bu sürenin nereye gittiğini henüz doğrulayamadı.
Go 1.26'nın Green Tea çöp toplayıcısının metaveri okuma biçimini değiştirip değiştirmediği sorulduğunda yazar bunu ölçtü ve etkinin ihmal edilebilir olduğunu gördü. Grafikler, bir mock allocator, BPF betikleri ve diğer yeniden üretim materyalleri bir eşlik eden depoda mevcut.
Neden önemli
40ms'lik bir stop-the-world duraklaması her goroutine'i durdurur — duraklama sırasında tamamlanan I/O'ları bekleyenler dahil — ve bu, gecikmeye duyarlı serviceler için görünür bir olaydır. Yazı ayrıca modern çekirdeklerde swap'ın zararsız olduğuna dair genel kabule bir karşı ağırlık: yazar, çekirdek geliştiricisi Chris Down ile swap'ın kötü bir şey olmadığı konusunda hâlâ hemfikir, ancak heap dışındaki tahliye edilebilir metaveriyi atomik olarak okumak zorunda olan bir izleme toplayıcısı spesifik bir arıza modudur. Ayırma yoğun Go iş yükleri için — yazarın kendi üretim vakası sık sık toplama tetikliyor — ders, swap'ın mikrosaniyeleri sessizce milisaniyelere dönüştürebilen bir değişken olarak görülmesi gerektiğidir.
- #go
- #garbage-collection
- #linux
- #swap
- #performance