- Go भाषा में undefined behavior लगभग नहीं के बराबर है, और इसकी सरल GC (garbage collection) semantics है
- Go में manual memory management संभव है, और इसे GC के साथ मिलकर किया जा सकता है
- Arena एक data structure है जो समान lifetime वाली memory को कुशलता से allocate करता है, और यह लेख बताता है कि Go में इसे कैसे implement किया जाए
- Mark and Sweep algorithm के ज़रिए GC memory को कैसे manage करता है, यह समझाया गया है
- Arena का उपयोग करके memory allocation performance बेहतर की जा सकती है, और यह कई optimizations के माध्यम से संभव है
- write barrier हटाना, memory reuse, chunk pooling आदि के ज़रिए performance बढ़ाने और GC का बोझ कम करने की कोशिश की गई है
- realloc implementation, Arena reuse और initialization (Reset) जैसी सुविधाओं के माध्यम से बड़े पैमाने की memory processing के लिए सुरक्षित और तेज़ patterns पेश किए गए हैं
Go में Arena-आधारित manual memory allocation का अवलोकन
- Go एक सुरक्षित भाषा है, क्योंकि इसमें स्पष्ट GC behavior और लगभग न के बराबर undefined behavior है
unsafe package का उपयोग करके GC की internal implementation के अनुरूप memory को सीधे नियंत्रित किया जा सकता है
- यह लेख बताता है कि Go में GC के साथ सहयोग करने वाला Arena structure-आधारित memory allocator कैसे बनाया जा सकता है
Arena की परिभाषा और ज़रूरत
- Arena एक ऐसी structure है जो एक ही lifetime वाले objects को कुशलता से allocate करने के लिए बनाई जाती है
- जहाँ सामान्य
append exponentially array को expand करता है, वहीं Arena नया block जोड़कर pointer उपलब्ध कराता है
- standard interface इस प्रकार है:
Alloc(size, align uintptr) unsafe.Pointer
Pointer और GC कैसे काम करते हैं
- GC memory को track (mark) और reclaim (sweep) करने के तरीके से काम करता है
- precise GC के लिए pointer bits नाम का metadata इस्तेमाल होता है, जो pointer locations की जानकारी देता है
- अगर Arena में pointers को गलत तरीके से संभाला जाए, तो GC pointers को track नहीं कर पाएगा, जिससे use-after-free error हो सकती है
Arena डिज़ाइन करने का तरीका
- Arena structure में ये fields होते हैं:
- सभी allocations को 8-byte alignment के साथ handle किया जाता है, और जगह कम पड़ने पर
nextPow2 से नया chunk बनाया जाता है
- chunk को
[]uintptr के बजाय struct { A [N]uintptr; P *Arena } type के रूप में allocate किया जाता है, ताकि GC Arena को track कर सके
Arena में pointer safety सुनिश्चित करने के तरीके
- जब केवल Arena के भीतर allocate किए गए pointers का उपयोग किया जाता है, तो GC पूरे Arena को जीवित रखता है
- pointer को Arena की ओर reference देने से पूरा Arena GC में survive करने की गारंटी पाता है
- Arena की allocation method यह काम करती है:
allocChunk() में Arena pointer को chunk के अंत में store किया जाता है
Performance benchmark के नतीजे
- सामान्य
new की तुलना में Arena allocation औसतन 2~4 गुना या उससे अधिक performance improvement दिखाती है
- GC load बहुत ज़्यादा होने पर भी Arena तरीका अधिकतम 2 गुना से अधिक बेहतर performance दिखाता है
- write barrier हटाने,
uintptr के उपयोग जैसी optimizations से छोटे allocations में अधिकतम 20% performance improvement मिलता है
Chunk reuse और heap हटाने की रणनीति
sync.Pool का उपयोग करके chunks को reuse किया जा सकता है
runtime.SetFinalizer() के माध्यम से Arena के समाप्त होने पर chunks को pool में वापस भेजा जा सकता है
- छोटे allocations में performance बहुत बेहतर होती है, लेकिन बड़े allocations में यह
new से धीमा हो सकता है
Arena initialization और reuse सुविधा
Reset() method से Arena को शुरुआती स्थिति में वापस लाया जा सकता है
- यह काफ़ी risky है, लेकिन memory को दोबारा allocate किए बिना उसी structure को reuse किया जा सकता है
- reuse के दौरान भी chunk reuse होने से performance में बड़ा सुधार मिलता है
Realloc सुविधा का implementation
- Arena में
realloc सुविधा implement करके सबसे हाल की allocation को dynamically expand किया जा सकता है
- यदि यह संभव न हो, तो नई memory allocate करके copy किया जाता है
निष्कर्ष और पूरा code उपलब्ध
- Go के GC mechanism को गहराई से समझकर, उसकी internal implementation के आधार पर Arena-आधारित memory manager पूरा किया गया है
- यह structure safety और performance दोनों देती है, और सही तरीके से इस्तेमाल करने पर बड़े data structures को संभालने में बहुत उपयोगी है
- पूरे implementation code में Arena struct और
New, Alloc, Reset, allocChunk, finalize आदि शामिल हैं
1 टिप्पणियां
Hacker News टिप्पणियाँ
यह लेख पढ़ने में मज़ेदार है
Reference[T]type से इसकी भरपाई करता हैहाल ही में Go में performance tuning करते समय, performance को अधिकतम करने के लिए मैंने बहुत मिलती-जुलती arena design का उपयोग किया
कुछ आसान सुधार
unsafe.Stringbyte slice से string को बिना allocation के पास करने में उपयोगी हैविषय से हटकर, लेकिन बगल में दिया गया minimap मुझे पसंद आया
जो लोग लंबा लेख पढ़ने में हिचकते हैं, उनके लिए सारांश
unsafe.Pointerसे raw bytes allocate किए जाएँ, तो GC arena के भीतर pointers को ठीक से नहीं देख पाता और गलती से उन्हें free कर सकता हैchunks) रखी जाती है जो उन सभी बड़े memory blocks की ओर इशारा करती है जो arena ने system से लिए हैंreflect.StructOfका उपयोग करके एक नया type बनाया जाता है, ताकि इन blocks में अतिरिक्त pointer fields शामिल होंसंबंधित: standard library में "memory regions" जोड़ने पर चर्चा
दिलचस्प बात है
Go ecosystem को टूटने से बचाने को प्राथमिकता देता है
एक छोटी meta note