- jemalloc के विकास का नेतृत्व करने वाले Jason Evans द्वारा लिखा गया यह प्रतिगामी लेख है, जिसमें लगभग 20 वर्षों तक चले jemalloc विकास की यात्रा को 5 चरणों में विभाजित कर देखा गया है, और सफलता-विफलता, ओपन सोर्स प्रोजेक्ट की सीमाएँ, तथा कंपनी के भीतर बदलावों के कारण आई गिरावट की प्रक्रिया को ईमानदारी से दर्ज किया गया है
- jemalloc memory allocator 2004 से शुरू हुआ और लगभग 20 वर्षों तक व्यापक रूप से इस्तेमाल किया गया, लेकिन हाल में Meta के आंतरिक बदलावों के कारण इसका आधिकारिक विकास रुक गया
- शुरुआती FreeBSD एकीकरण, Firefox प्रदर्शन समस्याओं का समाधान, Facebook द्वारा बड़े पैमाने पर अपनाया जाना जैसे कई चरणों में performance optimization और porting experience जमा हुआ
- storage fragmentation problem और scalability issues जैसी कई चुनौतियों से गुजरते हुए, performance improvements के साथ statistics collection, test infrastructure जैसी कई सुविधाएँ जोड़ी गईं
- Meta की corporate culture में बदलाव के साथ तकनीकी निवेश में कमी, core maintainers की अनुपस्थिति के कारण दीर्घकालिक विकास रुक गया
- Valgrind हटाना और external user feedback की कमी जैसी बातें ओपन सोर्स ecosystem में disconnect की संरचनात्मक सीमा बन गईं
- आगे fork के जरिए नए विकास की संभावना खुली है, लेकिन आधिकारिक main development अब आगे बढ़ने की संभावना नहीं है
jemalloc का अवलोकन
- jemalloc 2004 में पहली बार डिज़ाइन किया गया open source memory allocator है, जिसे performance और scalability सुधारने के लक्ष्य से विकसित किया गया, और 20 वर्षों तक प्रमुख open source projects तथा big tech infrastructure में सक्रिय रूप से इस्तेमाल किया गया
- हाल में main development रुक चुका है, इसलिए आगे fork या अलग-अलग संगठनों के स्तर पर maintenance की संभावना है
Phase 0: Lyken
- 2004 में Lyken नामक scientific computing programming language के विकास के दौरान इसकी शुरुआत एक manual memory allocator के रूप में हुई
- Lyken के अंदर का allocator मई 2005 में कार्यात्मक रूप से पूरा हो गया
- बाद में यह allocator FreeBSD में एकीकृत हो गया, और Lyken में इसे हटाकर केवल system allocator का एक thin wrapper छोड़ा गया
- इसे हटाने का कारण यह था कि FreeBSD integration के बाद system allocator की कमियाँ, जैसे thread-wise allocation tracking, अधिक स्पष्ट हो गई थीं
- दिलचस्प बात यह है कि बाद में jemalloc में वही statistics collection feature जोड़ी गई जिसकी जरूरत Lyken काल में थी
Phase 1: FreeBSD
- 2005 में जब multiprocessor computers आम हो रहे थे, FreeBSD phkmalloc का उपयोग कर रहा था, लेकिन वह parallel thread environment के लिए उपयुक्त नहीं था
- Lyken allocator में scalability सुधार का स्पष्ट लाभ था, इसलिए इसे FreeBSD में एकीकृत किया गया और जल्द ही इसका नाम jemalloc रखा गया
- लेकिन KDE applications आदि में गंभीर fragmentation problem सामने आई, जिससे इसके टिके रहने पर संदेह हुआ
- fragmentation का कारण size class के बिना unified space allocation method था, और शोध के बाद संरचना को बड़े पैमाने पर बदलकर size-segregated region algorithm अपनाया गया
- इस प्रक्रिया का विवरण 2006 के BSDCan paper में दर्ज है
Phase 1.5: Firefox
- 2007 में Mozilla Firefox 3 रिलीज़ से पहले Windows वातावरण में memory fragmentation एक बड़ा मुद्दा था
- jemalloc को Linux पर port करना आसान था, लेकिन Windows पर यह कठिन साबित हुआ
- FreeBSD libc में मौजूद jemalloc को Mozilla ने fork करके portability और compatibility सुधार पर काम किया
- समय के साथ Mozilla ने jemalloc upstream में कई सुधार दिए, लेकिन हमेशा fork version ने बेहतर performance दिखाई
- यह performance regression की समस्या थी या किसी खास environment के लिए optimization का असर, यह स्पष्ट नहीं है
Phase 2: Facebook
- 2009 में Facebook में शामिल होने के समय jemalloc की सबसे बड़ी बाधा tooling की कमी थी, जैसे profiling और leak detection
- इसे सुधारते हुए jemalloc 1.0.0 में pprof-compatible heap profiling फीचर जोड़ा गया
- development को Github पर ले जाने के बाद, users और external contributors के साथ test infrastructure, Valgrind support, JSON statistics, new page management सहित कई सुधार किए गए
- आंतरिक रूप से Facebook के विशाल telemetry system ने performance optimization और regression रोकने में बहुत मदद की
- 3.x: test infrastructure और Valgrind support जोड़ा गया
- 4.x: decay-based purging, JSON statistics जोड़ी गई
- 5.x: chunk से extent-based design में बदलाव, 2MiB huge page उपयोग की नींव रखी गई
- Facebook के अंदर telemetry-based performance analysis ने optimization में निर्णायक भूमिका निभाई
- 5.0.0 version में Valgrind support हटाने का फैसला इसलिए लिया गया क्योंकि इसका आंतरिक उपयोग नहीं हो रहा था, लेकिन Rust developers सहित बाहरी समुदाय ने तीखी प्रतिक्रिया दी
- इसके बाद Facebook/Meta के संगठनात्मक बदलावों के कारण jemalloc टीम छोटी हो गई, और रणनीति core technology investment से efficiency-focused business strategy की ओर मुड़ गई
- इसके चलते Huge Page Allocation जैसी बड़ी सुविधाओं का विकास ठहर गया, और कुछ काम पूरे नहीं हो सके
- 2017 में Evans के जाने के बाद, Qi Wang के नेतृत्व में कई वर्षों तक विकास बनाए रखा गया
- टीम नेतृत्व के हस्तांतरण के बाद भी कई contributors ने प्रोजेक्ट को बनाए रखा, लेकिन दीर्घकालिक vision manager की कमी रह गई
Phase 4: Stasis (ठहराव)
- वर्तमान में jemalloc का upstream development समाप्त हो चुका है, और Meta भी अपनी आंतरिक जरूरतों के अनुसार अलग दिशा में बढ़ रहा है
- मौजूदा codebase पर technical debt बहुत अधिक है, इसलिए बड़े पैमाने पर refactoring पहले करनी होगी
- Facebook/Meta की जरूरतें और external users की जरूरतें अब एक जैसी नहीं रहीं
- यदि भविष्य में development फिर शुरू किया जाता है, तो सैकड़ों घंटों के technical debt cleanup की आवश्यकता पहले होगी, और लेखक स्वयं इसके लिए प्रेरित नहीं हैं
dev branch या 5.3.0 के आधार पर external fork संभव है, इसलिए fork-आधारित नया प्रोजेक्ट कभी भी उभर सकता है
प्रतिगमन और सीख
- Valgrind support हटाने से पैदा हुआ संघर्ष external use cases की अपर्याप्त समझ से जुड़ा था
- Android में jemalloc इस्तेमाल हो रहा था, यह बात भी 2 साल बाद जाकर पता चली
- प्रोजेक्ट GitHub पर पूरी तरह खुला था, लेकिन बाहरी संगठनों से मुख्य contributors लंबे समय तक टिक नहीं पाए
- Firefox के Mike Hommey या CMake migration के प्रयास भी अधूरे रह गए
- अनुभव के अनुसार, केवल open कर देने भर से कोई प्रोजेक्ट sustainable independent project नहीं बन जाता
- इस बात पर जोर दिया गया है कि open source केवल public होने से नहीं चलता; core contributors का विकास और governance सुनिश्चित करना अनिवार्य है
समापन टिप्पणी
- jemalloc, 25 वर्षों से अधिक समय तक garbage collection समर्थक रहे लेखक के लिए भी एक विशेष अनुभव था
- लेखक अब फिर से garbage collection systems के विकास पर ध्यान दे रहे हैं, लेकिन jemalloc में सहयोग करने वाले सभी लोगों के प्रति गहरी कृतज्ञता व्यक्त करते हैं
2 टिप्पणियां
पूरे लेख का अनुवादित संस्करण भी उपलब्ध है.
https://rosettalens.com/s/ko/jemalloc-postmortem
Hacker News राय
मैं upstream repository को archive करने के फ़ैसले को समझ सकता हूँ। Meta छोड़ने से पहले हमारी Jemalloc टीम के पास GitHub पर आने वाले हर तरह के issues संभालने की पर्याप्त क्षमता नहीं थी (उदाहरण के लिए, किसी ने यह issue खोला था कि Itanium environment में tests pass नहीं हो रहे, और वह घटना मुझे थोड़ी मज़ेदार लगी थी)। फिर भी, यह स्थिति देखकर अफ़सोस होता है। आज भी मुझे लगता है कि jemalloc, general-purpose malloc implementations में performance और ease of use दोनों के हिसाब से सबसे अच्छा विकल्प है। TCMalloc भी शानदार है, लेकिन अगर आप bazel इस्तेमाल नहीं करते, तो इसे इस्तेमाल करना वाकई बहुत मुश्किल है (हालाँकि अब bazel 7.4.0 में
cc_static_libraryजुड़ने से static library के रूप में export करना थोड़ा आसान हुआ है, फिर भी यह बात काफ़ी हद तक बनी हुई है)। मैं Qi से पूछने का सोच रहा हूँ कि repository को फिर से archive करने से पहले क्या वह एक आख़िरी 6.0 release बना सकते हैं। अगर यह अंतिम release हो, तो default settings को थोड़ा modernize करना अच्छा रहेगा। उदाहरण के लिए, नाम के उलट काफ़ी भ्रम पैदा करने वालेcache oblivioussetting को default से disable कर देना बड़ा सुधार होगा, ताकि 16 KiB size-class बेवजह 20 KiB तक न फूल जाए। मैं पुराने फ़ैसले (यानि Jason के शुरुआती निर्णय) की आलोचना नहीं कर रहा; उस समय Qi और David के साथ हुई चर्चा में यह बात काफ़ी तर्कसंगत थी कि तब सामान्य रूप से TLB associativity आज की तुलना में काफ़ी कम थी। इसी तरह, defaultpage sizeको 4 KiB से बढ़ाकर किसी बड़े मान (लगभग 16 KiB) पर ले जाना भी अच्छा बदलाव होगा। इससे large size-class का threshold (जहाँ कई allocations slab में जाने के बजाय एक निश्चित size से ऊपर हर allocation अलग range में जाता है) 16 KiB से बढ़कर 64 KiB हो जाएगा, जो काफ़ी असरदार है। Meta छोड़ने से पहले मैंने एक बड़े internal service पर यह बदलाव लागू करने की संभावना देखी थी, और यह ऐसा optimization था जिसमें CPU usage कुछ प्रतिशत कम होता था, बदले में RAM fragmentation की वजह से memory usage थोड़ा बढ़ता था। इसके अलावा भी कुछ चीज़ें हैं जिन्हें मैं बदलना चाहूँगा (जैसेmetadata_thpका defaultdisabledसेautoकरना, slabs के extent sizing को exact page-size multiples से हटाकर fragmentation कम करने के लिए लगभग 1% waste स्वीकार करना, आदि)। फिर भी, ऊपर बताई गई settings सबसे बड़े बदलाव होंगीItanium test suite failure issue खोलने वाला व्यक्ति मैं ही था
ऐसे असली अनुभव और insider insights ही वजह हैं कि मैं Hacker News पर बार-बार लौटता हूँ। मैं जानना चाहता हूँ कि TCMalloc को bazel के बिना इस्तेमाल करना इतना मुश्किल क्यों है (मैं सच में जिज्ञासा से पूछ रहा हूँ)
काश ऐसी अहम अंदरूनी जानकारी official docs या blog posts जैसे विस्तृत materials में सार्वजनिक होती। अभी official documentation बहुत कमज़ोर लगती है। Meta के अंदर हुए इतने काम का know-how समय के साथ भुला दिए जाने से पहले साझा किया जाना चाहिए
यह थोड़ा अफ़सोसजनक है कि इतना शानदार software build और integration की जटिलता की वजह से ठीक से इस्तेमाल नहीं हो पाता
आपने कहा कि ‘Jemalloc टीम के पास GitHub पर आने वाले random issues संभालने की पर्याप्त क्षमता नहीं थी’, तो मेरी जिज्ञासा है: Meta में इस project को maintain करने वाले लोग काफ़ी थे, फिर भी issue handling सुचारु क्यों नहीं थी? अगर मैं स्थिति को ग़लत समझ रहा हूँ, तो कृपया सुधारें
मैं बताना चाहता हूँ कि Jason का काम हमारे व्यवसाय पर कितना बड़ा असर डालता है। हमारी कंपनी हर दिन करोड़ों images/videos process करती है, यानी काफ़ी बड़े scale पर काम करती है। शुरुआती कुछ वर्षों में memory fragmentation की वजह से हमने बहुत कष्ट झेला। फिर एक दिन हमने jemalloc अपनाया, और Dockerfile में सिर्फ़ दो लाइनें बदलने से हमारी सारी समस्याएँ हल हो गईं। आज हम अरबों revenue वाली कंपनी हैं, और हमारी सभी services तथा Dockerfiles में jemalloc इस्तेमाल होता है। दिल से बहुत धन्यवाद
व्यवहार में बहुत-सी golang-based image processing services jemalloc की सिफ़ारिश करती हैं या उसे इस्तेमाल करती हैं। resize-images topic की top 3 services में (2025-06-13 के अनुसार) imaginary इसे Dockerfile में इस तरह इस्तेमाल करती है, imgproxy के लिए archived docs का हवाला imaginary repo के भीतर भी दिया जाता है। imagor भी इस जगह jemalloc इस्तेमाल कर रहा है
मैं सच में जिज्ञासा से पूछ रहा हूँ (बिल्कुल तंज़ नहीं): क्या आपने donation भी किया है? पैसे से आभार जताना क्या सबसे अच्छा धन्यवाद नहीं है?
‘jemalloc को Rust binaries से उम्मीद से जल्दी हटा दिया गया’ वाली राय पर, मैं साझा करना चाहता हूँ कि वह issue वास्तव में कई कारणों में से सिर्फ़ एक था। इस comment में संबंधित background देखा जा सकता है। और jemalloc पूरी तरह हटाया गया था, उस issue के पहली बार उठने के पूरे 2 साल बाद (संदर्भ: यह PR)
कई वर्षों से मेरे द्वारा बनाए गए हर game engine में jemalloc का इस्तेमाल लगभग आदत बन चुका है। win32 environment में यह default allocator से कहीं तेज़ है, और सभी platforms पर एक ही allocator इस्तेमाल करने का फ़ायदा भी बड़ा है। मुझे jemalloc के बारे में FreeBSD में इसके integration के कारण पता चला था, और उसके बाद से मैं लगातार jemalloc ही इस्तेमाल कर रहा हूँ। मुझे गर्व है कि jemalloc की वजह से बहुत-से game players को आनंद मिला है
यह एक अच्छा लेख लगा — मैं जानना चाहता हूँ कि क्या Facebook (अब Meta) अब jemalloc ख़ुद इस्तेमाल नहीं करता, या सिर्फ़ maintenance mode में है। क्या यह भी संभव है कि वे tcmalloc या किसी और allocator पर चले गए हों? वहाँ एक पंक्ति थी: ‘Facebook infrastructure engineering में core technology investments से ज़ोर हटकर ROI-केंद्रित सोच पर आ गया’
मुझे Meta छोड़े लगभग 2 साल हो चुके हैं (और मेरा अनुमान है कि अब भी बहुत कुछ नहीं बदला होगा), लेकिन jemalloc अभी भी Meta के सभी binaries में statically linked होकर इस्तेमाल होता है। tcmalloc या किसी और allocator पर आसानी से switch किया जा सकता है या नहीं — इसका जवाब है कि jemalloc कंपनी के internal ecosystem में बहुत गहराई से जुड़ा हुआ है, इसलिए इसे बदलना सोचे से कहीं कठिन है। Strobelight telemetry plumbing से लेकर jemalloc के अनुरूप इस्तेमाल होने वाले अनेक extensions (जैसे custom extent hooks का सीधे उपयोग करने वाले manual arenas), और यहाँ तक कि अधिकांश applications का jemalloc की विशेषताओं का पूरा लाभ लेने के लिए evolve होना — सब कुछ आपस में गुँथा हुआ है
हाल का बड़ा बदलाव यह है कि jemalloc के लंबे समय के main maintainers सभी जा चुके हैं। लेकिन विडंबना यह है कि पहले की तुलना में अब Facebook के भीतर इस project में रुचि बढ़ी है, और हाल के कुछ विवादास्पद issues के बाद उम्मीद है कि आगे का रास्ता Qi, Jason और बाहरी users — सभी के नज़रिए को ध्यान में रखकर तय होगा
Meta अभी भी अपना fork version यहाँ सक्रिय रूप से विकसित कर रहा है
Firefox से लेकर Facebook तक लंबे समय में फैले इस प्रभावशाली काम का हिस्सा बन पाना मेरे लिए सम्मान की बात थी
सही समय पर मैं भी यहाँ धन्यवाद कहना चाहता हूँ। मुझे उम्मीद नहीं थी कि यह लेख आज पोस्ट होगा, लेकिन इस लंबी यात्रा के छोटे-से हिस्से का भी हिस्सा बनना सम्मान की बात थी। मैं @je, qi, david और उस समय तथा उसके बाद योगदान देने वाले सभी लोगों को धन्यवाद कहना चाहता हूँ
मुझे लगता है कि core technologies में लगातार निवेश जारी रखने देने वाली आपकी leadership ने भरपूर फल दिया। GraphQL, PyTorch, React जैसी innovations के पीछे यही बुनियाद थी
“जब विकल्प असंभव हों, तो लोग 1) अत्यधिक दबाव में खराब निर्णय लेते हैं, 2) अत्यधिक दबाव में समर्पण कर देते हैं, या 3) बस कोई चक्करदार रास्ता खोजते हैं” — FTA का यह उद्धरण किसी workplace atmosphere के रूप में कल्पना करना भी कठिन है
मुझे लगता है jemalloc, macOS में malloc/free को LD_PRELOAD जैसी सहजता से override कर पाने वाला एकमात्र allocator है (कम से कम 2020 के आसपास तक)। यह zone-based तरीके से आसानी से default allocator की जगह आ सकता है, और Apple की allocator-specific requirements के साथ भी अच्छी तरह फिट बैठता है। अन्य third-party allocators अक्सर इन्हीं requirements की वजह से विफल रहे हैं
हालाँकि, यह तरीका इस धारणा पर निर्भर करता है कि macOS system allocator अपनी internal structures नहीं बदलेगा, इसलिए मुझे याद है कि Apple के बदलावों से यह कम-से-कम दो बार टूटा था
मेरी जानकारी में mimalloc भी इसी तरह काम कर सकता है, लेकिन मैं पूरी तरह निश्चित नहीं हूँ
मुझे हमेशा लगा कि jemalloc, glibc के malloc की तुलना में हर पहलू में बेहतर है, और benchmarks में भी यह लगातार बेहतर performance दिखाता है, तो फिर यह default allocator क्यों नहीं है — यह सवाल एक outsider के रूप में मेरे मन में था
FreeBSD में jemalloc पहले से ही default है। अगर आप malloc बदलना चाहते हैं, तो libc को भी FreeBSD libc से बदलना ज़्यादा आसान होगा, और फिर kernel को भी FreeBSD पर ले जाना स्वाभाविक होगा। जब Facebook के साथ merger हुआ था, तो मैं हमारी तरफ़ के एक कर्मचारी को jemalloc के बारे में उत्साहित होकर बता रहा था, लेकिन हम पहले से FreeBSD पर थे, इसलिए उनके लिए यह बस सामान्य बात थी
मैं allocator engineer नहीं हूँ, इसलिए यह विशेषज्ञ राय नहीं है, लेकिन मैंने पहले एक OS allocator बनाए रखने वाले engineer से बात की थी। उनके अनुसार, custom allocators अक्सर एक process को memory allocation में अत्यधिक फ़ायदा दे देते हैं, लेकिन system-wide allocation fairness को ख़राब कर सकते हैं। system allocator के नज़रिए से, अगर अलग-अलग processes बिल्कुल अलग patterns अपनाएँ, तो पूरे system को optimize करना कठिन हो जाता है। इसलिए ज़्यादातर service environments में jemalloc की सिफ़ारिश इस धारणा पर की जाती है कि ‘इस समय सिर्फ़ मेरी process मायने रखती है’
मुझे नहीं लगता कि jemalloc के default allocator न बनने का कोई तकनीकी कारण है। FreeBSD में तो यह default है ही (जैसा लेख में कहा गया है)। मेरी समझ में यह मुद्दा तकनीकी से ज़्यादा राजनीतिक है
jemalloc वास्तविक बड़े production environments में साबित हो चुका है, इसका license बहुत permissive है और इसका performance भी सिद्ध है। फिर glibc malloc पर अड़े रहने की वजह आख़िर क्या है — ‘वैचारिक शुद्धता’ और legacy inertia के अलावा इस स्थिति से लाभ किसे है, यह जानने की सच में जिज्ञासा है। मैं उल्टा पूछना चाहता हूँ कि अब भी ‘compatibility’ को बहाना क्यों बनाया जाता है
पहले alternative allocators की एक बड़ी समस्या यह थी कि वे freed memory को कभी OS को वापस नहीं लौटाते थे और सिर्फ़ dirty pages के रूप में पकड़े रहते थे (हालाँकि बाद में इसमें सुधार हुआ, लेकिन यह allocators की प्राथमिकताओं के अंतर का एक प्रतिनिधि उदाहरण है)। और वास्तव में, अधिकांश processes या तो सिर्फ़ एक main thread चलाती हैं या फिर लगभग idle threads ही रखती हैं। multi-threading-optimized allocators ऐसे environments में overkill हो सकते हैं और उल्टा बोझ बन सकते हैं। साथ ही, यह बात भी ज़्यादातर लोग नहीं सोचते कि page को zero करने की लागत kernel उठाए या user process अपनी internal reuse के लिए zero करे — व्यावहारिक रूप से उसमें बहुत बड़ा अंतर नहीं होता
बेहतर होता कि blog post link को GitHub repository में जोड़ दिया जाता। आगे repository पर आने वाले लोगों के लिए इस context को जानना और संदर्भ के रूप में देखना महत्वपूर्ण है