- JVM की अंदरूनी जानकारी को छोटी इकाइयों में बांटकर कवर करने वाली ongoing मिनी-पोस्ट सीरीज़ है, जहां हर लेख एक विषय, टेस्ट, benchmark या observation पर केंद्रित है
- हर पोस्ट का लक्ष्य 5–10 मिनट में पढ़े जा सकने लायक लंबाई रखना है, और यह मानकर चलती है कि JVM के घटक आपस में interact करते हैं
- आधार और चर्चा anecdotal हो सकते हैं, और errors, consistency, style, grammar, duplication आदि की पर्याप्त समीक्षा न हुई हो सकती है, इसलिए इसे ज्यों-का-त्यों भरोसेमंद मानने में सावधानी चाहिए
- पूरी series bundle ePUB, MOBI, PDF में उपलब्ध है; high-quality conversion के कारण PDF का size दर्जनों MB के स्तर का है
- अलग-अलग लेखों का index Compiler, Runtime, GC, Library axes में बंटा है, और lock optimization, TLAB, GC pauses,
String.intern(), safepoint, compressed references, conditional moves जैसे JVM internals विषयों को कवर करता है
सीरीज़ पढ़ते समय मान्यताएं
- JVM Anatomy Quarks JVM की बुनियादी जानकारी को छोटे लेखों के रूप में व्यवस्थित करने वाली ongoing mini-post series है
- हर पोस्ट एक विषय, test, benchmark या observation में गहराई से जाने के format में है
- किसी एक पोस्ट को अलग से देखने पर context कम हो सकता है, और कवर किए गए अधिकतर तत्व आसानी से एक-दूसरे के साथ interact करते हैं
- लेखों के आधार और चर्चा anecdotal हो सकते हैं, और errors, consistency, style, grammar, meaning, duplication आदि की पर्याप्त समीक्षा न हुई हो सकती है
- content का इस्तेमाल या उस पर भरोसा करते समय जोखिम पाठक को खुद उठाना होगा
Bundle files और index structure
- पूरी series bundle तीन formats में उपलब्ध है
- ePUB सबसे छोटा है, MB से कम, और Pandoc HTML-to-ePUB पर आधारित है
- MOBI छोटा है, MB स्तर का, और KindleGen ePUB-to-MOBI पर आधारित है
- PDF दर्जनों MB के स्तर का बहुत बड़ा है, और wkhtmltopdf HTML-to-PDF आधारित high-quality output है
- अलग-अलग index Compiler, Runtime, GC, Library categories से बने हैं
विषयवार लेखों की सूची
-
Compiler-केंद्रित आइटम
#1: Lock Coarsening and Loops#14: Constant Variables#15: Just-In-Time Constants#16: Megamorphic Virtual Calls#17: Trust Non-Static Final Fields#18: Scalar Replacement#19: Lock Elision#20: FPU Spills#25: Implicit Null Checks#27: Compiler Blackholes#28: Frequency-Based Code Layout#29: Uncommon Traps#30: Conditional Moves
-
Runtime और GC से जुड़े आइटम
- ये JVM execution के दौरान memory और pause behavior को कवर करने वाले लेख हैं
#2: Transparent Huge Pages#4: TLAB Allocation#5: TLABs and Heap Parsability#6: New Object Stages#7: Object Initialization Costs#9: JNI Critical and GC Locker#22: Safepoint Polls
-
GC-केंद्रित आइटम
- मुख्य रूप से collector design और heap behavior को कवर करता है
#3: GC Design and Pauses#11: Moving GC and Locality#13: Intergenerational Barriers#21: Heap Uncommit
-
Runtime-केंद्रित आइटम
- JVM execution environment और object representation को कवर करने वाले लेख हैं
#12: Native Memory Tracking#23: Compressed References#24: Object Alignment#26: Identity Hash Code
-
Library या mixed classification वाले आइटम
- Library तक शामिल आइटम के रूप में
#10: String.intern()है - Compiler और Runtime दोनों के साथ दिखाए गए आइटम के रूप में
#16,#25,#29,#30हैं
- Library तक शामिल आइटम के रूप में
1 टिप्पणियां
Hacker News टिप्पणियाँ
https://shipilev.net/jvm/anatomy-quarks/17-trust-nonstatic-f... वाकई एक अफसोसजनक उदाहरण है
कुछ frameworks ने JNI और reflection का जरूरत से ज्यादा इस्तेमाल करके उन
finalfields को बदल दिया, जिन्हें मूल रूप से immutable होना चाहिए था, इसलिए user code उन महत्वपूर्ण optimizations से वंचित रह जाता है जो system-provided classes के लिए ही संभव हैंplatform, खासकर compiler और runtime, को future optimizations की गुंजाइश बचाए रखने के लिए semantic constraints को बहुत सख्ती से लागू करना चाहिए
वास्तव में
finalको बदलने की जरूरत बहुत कम code को पड़ती है, और अभी भी यह काम केवल अपने module के अंदर की classes या explicitlyopenकी गई classes तक सीमित है, इसलिए आगे चलकर यह ऐसा होगा किfinalबदलने की कोशिश करने वाले module को application की तरफ से permission देनी होगीयह हाल में native calls और unsafe memory access पर लागू किए गए तरीके जैसा है
[1]: https://openjdk.org/jeps/8305968
finalलगा दो वाली मूल गलती कर दीइसी वजह से अब tests में
finalclasses को आसानी से mock नहीं किया जा सकता, और mocking tools कोfinalclasses को mock करने के लिए bytecode manipulation तक करनी पड़ती हैउदाहरण के लिए Google के अंदर Effective Java एक requirement है, इसलिए public GDrive API में भी
finalclasses हैं, जबकि बाहरी APIs ही वे चीज़ें हैं जिन्हें आप सबसे ज्यादा mock करना चाहेंगेSystem.outवाला मामला खुद Java की समस्या हैhttps://docs.oracle.com/javase/specs/jls/se7/html/jls-17.htm...
ऐसा precedent मौजूद हो तो यह हैरानी की बात नहीं कि दूसरों ने भी इसे स्वीकार्य तरीका समझ लिया
उचित bypass procedure से गुजरने पर इन्हें bypass किया जा सकना चाहिए
असली मुद्दा safety है, क्योंकि immutable चीज़ों को बदलकर SEGV कराया जा सकता है, और access modifiers जिस चिंता को संभालना चाहते हैं, वह मूलतः यही है
finalजैसा बना देने वाला दुर्भावनापूर्ण तीन-लाइन का code लिखा थाअच्छा होता अगर यह करना रोका गया होता, लेकिन business requirements थीं
थोड़ी अलग बात है, लेकिन Apple ने नया Swift Java bridge जारी किया है और यह काफी शानदार है
यह JNI और Panama दोनों को support करता है, और पिछले हफ्ते इसे Android पर port किया जा रहा था
https://github.com/swiftlang/swift-java
language interoperability की वजह से सही मामलों में एक ही library को कई platforms पर साझा किया जा सकता है
अब तक यह काम सिर्फ C++ में, और जरूरत पड़ने पर C API जोड़कर किया जाता था, लेकिन जब खुद C++ की जरूरत न हो तो वह स्वाभाविक रूप से पसंदीदा भाषा नहीं है
हालांकि cost को लेकर चिंता है. अगर mobile app में Swift आसानी से Kotlin library को call कर सकता है, तो क्या iOS app को किसी न किसी रूप में JVM जैसी चीज़ load नहीं करनी पड़ेगी, और उल्टा Android app से Swift को call करें तो Swift runtime load करना पड़ेगा
आखिरकार overhead तो आएगा ही
डर है कि कहीं आगे चलकर यह आम न हो जाए कि developers Swift library पर depend करें, वह library Kotlin library पर depend करे, JVM चालू करे, और फिर JNI के जरिए C++ को call करे
यह कुछ-कुछ modern package managers जैसा लगता है, जहाँ direct dependencies तो गिनती की होती हैं, लेकिन “इतना आसान है कि ध्यान ही नहीं दिया” के नतीजे में program देखते-देखते 100 से ज्यादा transitive dependencies ले आता है
अच्छा लगा कि इस बेहतरीन लेख-श्रृंखला को यहाँ साझा किया गया
इस series को पढ़ते हुए मैंने JVM के बारे में बहुत कुछ सीखा
खासकर Java में जिसे आम तौर पर “stack allocation” कहा जाता है, वह गलत है—इस बारे में यह लेख मुझे बहुत पसंद है: https://shipilev.net/jvm/anatomy-quarks/18-scalar-replacemen...
JVM वास्तव में escape analysis + scalar replacement करता है
इन लेखों की लंबाई मुझे पसंद है
कुछ ही मिनटों में एक लेख पूरा पढ़ा जा सकता है, और चाहें तो benchmark लोकल में चलाकर भी देखा जा सकता है
अगर आपने JVM-आधारित language के साथ कुछ साल काम किया है, तो यह लेख-संग्रह वाकई बहुत दिलचस्प है
याद है, कुछ साल पहले जब मैंने इन्हें पहली बार पढ़ना शुरू किया था
क्या किसी को पता है कि इस series का नाम ‘JVM Anatomy Park’ से क्यों बदला गया?
मैं Java को लगभग भूल-सा गया हूँ
नया प्रोजेक्ट Java में शुरू करने का खयाल बिल्कुल नहीं आता
तेज़ development और flexibility चाहिए तो Python, garbage collection के साथ बहुत सारी I/O concurrency संभालनी हो तो Go, compiled होते हुए संतुलित और अच्छी language चाहिए तो Swift, और performance व safety वाली compiled language चाहिए तो Rust चुनूँगा
यह बस मेरी personal preference है, और मुझे पता है कि Kotlin ने Java को इस्तेमाल में ज़्यादा आसान बनाया है, फिर भी मेरी भावना यही है
Java की मुख्य ताकत यह है कि Java experience वाले developers लगभग अनंत संख्या में मिल जाते हैं, existing libraries बहुत विशाल हैं और उनमें से काफ़ी enterprise-oriented हैं, बहुत सारे contributors वाले बहुत बड़े codebase को manage करना आसान है, और दशकों में विकसित standard VM बहुत मज़बूत, काफ़ी तेज़, और लगभग हर platform पर supported है
शुरुआती 2000s जितना, बल्कि enterprise में भी, इसका दबदबा अब उतना नहीं है, और यह एक typical “blub” language है, लेकिन अगर आप enterprise scale की अपेक्षा कर रहे हैं और pure performance से ज़्यादा कई developers तक scale करना महत्वपूर्ण है, तो यह पूरी तरह समझदारी भरा विकल्प है
मुझे Rust पसंद है, लेकिन मेरी रोज़ी-रोटी Java से चलती है
modern frameworks और AI assistance की वजह से कुछ ही दिनों में एक ठीक-ठाक backend खड़ा किया जा सकता है
अगर आप solo technical cofounder हैं, तो जल्दी MVP बनाने के लिए Java या Kotlin और थोड़ा frontend stack जानना ही काफ़ी है, और व्यवहार में coding के अलावा कामों पर कहीं ज़्यादा समय जाता है, इसलिए language features का फ़र्क कम महत्वपूर्ण हो जाता है
अगर mobile native में जाते हैं, तो Swift दूसरी language बन सकती है
साथ ही, कुछ समय तक scalability पहली समस्या होने की संभावना भी कम है. पहले team scaling आती है, और performance bottleneck अक्सर बहुत बाद में दिखते हैं
Java बड़ी teams के लिए उपयुक्त है
business नज़रिए से अगर आप बड़ा talent pool, तेज़ delivery cycle, और ऐसा कुछ चाहते हैं जो लंबे समय तक core stack बना रह सके, तो Java या Kotlin शायद सबसे बेहतर हैं
अगर आप किसी खास developer वर्ग को आकर्षित करने के लिए cool tech को perks की तरह पेश करना चाहते हैं, या कोई दुर्लभ business case है, तो Go या Rust चुन सकते हैं
Python अकादमिक जगत और bootcamp में लोकप्रिय है, लेकिन general-purpose backend में इसका business value क्या है, इस पर मुझे ईमानदारी से पक्का नहीं है
मैं पूरे JVM को नज़रअंदाज़ नहीं करूँगा. JVM एक engineering masterpiece है और आजकल तेज़ी से विकसित हो रहा है. Loom, Panama, Leyden आदि देखिए
इसलिए लगभग हर चीज़ के लिए Java काफ़ी स्पष्ट रूप से एक अच्छा विकल्प है
Java 21+ के साथ Kotlin, चाहे I/O-केंद्रित service हो या लगभग कोई भी service, मेरी पहली पसंद का संयोजन है
इसे इस्तेमाल करना वाकई बहुत आसान है, और virtual threads की वजह से Go जितना सरल और efficient code लिखा जा सकता है, साथ ही दुनिया के सबसे बड़े और बेहतरीन library ecosystem में से एक का लाभ भी मिलता है
मेरा उद्देश्य Go या Python को नीचा दिखाना नहीं है. अगर वे आपके पसंदीदा tools हैं, तो वे पूरी तरह ठीक हैं
बस इतना कि Java उतना अप्रासंगिक नहीं हुआ है जितना आप सोचते हैं