स्वैप के कारण हुआ 40ms का Go garbage collector pause
Go में 40 ms के stop-the-world pauses का एक मामला, जो उस garbage collector से जुड़ा था जिसने swap out हो चुकी metadata को touch किया, इस बात पर व्यापक चर्चा छेड़ता है कि GC का operating-system memory pressure से क्या संबंध है। टिप्पणीकार बहस करते हैं कि low-latency systems को GC languages से पूरी तरह बचना चाहिए, swap disable करनी चाहिए, या `mlock`, cooperative या swap-aware collectors, और on-the-fly GC या reference counting जैसे alternative algorithms अपनाने चाहिए। यह चर्चा throughput और latency के बीच trade-off को उजागर करती है, और सुझाती है कि runtime design और OS-level APIs दोनों वास्तविक pause behavior को काफी प्रभावित करते हैं.
Go का GC डिज़ाइन और “on-the-fly” विकल्प
- Go पहले से ही एक concurrent mark-sweep GC का उपयोग करता है, जिसके typical pause times बहुत कम होते हैं।
- कुछ लोग पूछते हैं कि Go classic “on-the-fly” GC algorithms (जैसे DLG-style) क्यों नहीं अपनाता, जिनका लक्ष्य zero stop-the-world (STW) pauses होता है।
- कुछ अन्य लोग कहते हैं कि Go की टीम संभवतः इन algorithms को जानती है; latency बनाम throughput के tradeoffs और stack/coroutine scanning की जटिलता मौजूदा choices को समझा सकती है।
- Fil-C के alternative on-the-fly algorithm का उल्लेख Go के coroutine model के लिए संभावित रूप से प्रासंगिक बताया गया है।
Swap, Page Faults, और Latency Spikes
- मुख्य समस्या: जब GC metadata या heap pages swap out हो जाती हैं, तो STW sections में बहुत सारे page faults इकट्ठा हो सकते हैं, जिससे memory pressure बड़े latency spikes में बदल जाती है।
- कुछ लोग तर्क देते हैं कि यदि आपको latency की चिंता है, तो swap disable कर देना चाहिए; अन्य कहते हैं कि इससे stalls केवल code pages पर शिफ्ट हो जाते हैं और OOM भी हो सकता है।
- बताया गया कि kernel anonymous और file-backed pages को कैसे evict करता है; swap disable करने से paging रुकती नहीं है, बस यह बदलता है कि क्या evict होगा।
- सुझाए गए mitigations: critical regions या metadata के लिए
mlock/mlockall, cgroups और swappiness का सावधानीपूर्वक उपयोग, या swap storms की तुलना में OOM-kill को बेहतर मानना।
Reference Counting बनाम Tracing GC
- कई पोस्टरों का दावा है कि reference counting (RC) अधिक predictable performance देती है; अन्य लोग इसका विरोध करते हैं और ये कारण देते हैं:
- Cascaded deallocations arbitrarily लंबे हो सकते हैं।
- High overhead, खासकर multithreaded programs में atomic RC के साथ।
- Cycles और NUMA/locking से जुड़ी समस्याएँ।
- कुछ लोग hybrid या deferred RC schemes को पसंद करते हैं; अन्य जोर देते हैं कि उद्योग के दशकों के अनुभव से पता चलता है कि pure RC के महत्वपूर्ण tradeoffs हैं।
OS–GC सहयोग और Swap-Aware Designs
- उठाए गए विचार:
- ऐसा swap-aware GC जो STW phases में उपयोग होने वाले pages को prefetch या lock करे।
mlock,madvise,mincore, या page-touching जैसे मौजूदा APIs का उपयोग करके residency प्रबंधित करना।- गहरा OS–GC सहयोग (जैसे bookmark collectors, cooperative memory management, या
madviseके साथ समन्वय करने वाले region-based GCs)।
- कुछ लोगों को यह एक missed research/practical opportunity लगता है; अन्य लोगों को संदेह है कि ऐसा गहरा integration जल्द व्यापक रूप से आएगा।
Language Choice और Latency Requirements
- कई टिप्पणियाँ इसे एक और data point मानती हैं: जहाँ कभी-कभार GC latency स्वीकार्य हो, वहाँ Go उपयोग करें; strict low-latency जरूरतों के लिए Rust/C++ (RAII/manual control) चुनें।
- Discord case का उल्लेख किया गया: बहुत कम garbage होने पर भी, एक बड़ा object graph और periodic GC अस्वीकार्य tail latency पैदा कर सकता है, जिससे non-GC language में rewrite करने की प्रेरणा मिली।