क्या आपने कभी सोचा है कि जावा की वस्तुएं अंदर से कैसी दिखती हैं?
बिल्ली के नीचे जावा ऑब्जेक्ट हेडर का एक विस्तृत विवरण होगा, इसमें क्या है और यह कितनी मेमोरी लेता है।
शुरुआत करने के लिए, याद रखें कि jvm में मेमोरी में किसी भी ऑब्जेक्ट में ऑब्जेक्ट हेडर और ऑब्जेक्ट वैरिएबल्स (लिंक और प्राइमिटिव्स) होते हैं। साथ ही, ऑब्जेक्ट का अंतिम आकार 8 बाइट्स के कई बनने के लिए विस्तारित किया जा सकता है।
प्रत्येक ऑब्जेक्ट का शीर्षक (सरणी को छोड़कर) दो मशीन शब्दों के होते हैं - चिह्न शब्द और वर्ग शब्द । सरणी की लंबाई का वर्णन करने के लिए Arrays में अतिरिक्त 32 बिट्स हैं।
मार्क वर्ड स्टोर की पहचान हैशकोड, कचरा कलेक्टर द्वारा उपयोग किए जाने वाले बिट्स और ताले के लिए उपयोग किए जाने वाले बिट्स। आप हमेशा OpenJDK के प्रकारों में अधिक विवरण पा सकते हैं markOop.hpp ।
एक वर्ग शब्द अपने आप में कक्षा के लिए एक सूचक को संग्रहीत करता है, अर्थात्, उस स्थान पर जहां इस डेटा प्रकार के बारे में जानकारी निहित है: विधियाँ, एनोटेशन, विरासत, और बहुत कुछ। अधिक विवरण हमेशा केलज.हैप के संबंधित OpenJDK प्रकार में भी पाए जा सकते हैं।
आइए अब ऑब्जेक्ट के शीर्षक और विशेष रूप से चिह्न शब्द पर करीब से नज़र डालें
32 बिट jvm

जैसा कि आप तालिका से देख सकते हैं, मार्क शब्द की सामग्री वस्तु की वर्तमान स्थिति के आधार पर बहुत भिन्न हो सकती है।
ऑब्जेक्ट की सामान्य स्थिति (बायस्ड_लॉक = 0, लॉक = 01)
- Ident_hashcode एक ऐसी वस्तु का हैश है जो आलसी दिखाई देता है। यदि ऑब्जेक्ट में पहली बार System.identityHashCode (obj) कॉल है, तो इस हैश की गणना की जाएगी और ऑब्जेक्ट हेडर को लिखा जाएगा।
अन्य राज्यों में, जब विभिन्न धाराएँ किसी वस्तु के लिए प्रतिस्पर्धा करती हैं, तो Ident_hashcode को ऑब्जेक्ट हेडर में नहीं, बल्कि ऑब्जेक्ट के मॉनिटर में संग्रहीत किया जाएगा। - उम्र - कचरे के संग्रह की संख्या का अनुभव। जब उम्र अधिकतम-अवधि-सीमा संख्या तक पहुँच जाती है,
ऑब्जेक्ट पुरानी पीढ़ी के कूल्हे क्षेत्र में जाता है। - पक्षपाती_लोक - 1 होता है यदि पक्षपाती लॉकिंग इस ऑब्जेक्ट के लिए सक्षम है, अन्यथा 0।
थोड़ा औरजब बायस्ड लॉकिंग को चालू किया जाता है, तो ऑब्जेक्ट चलता है क्योंकि यह पहली वस्तु थी जिसने इसके मॉनिटर को कैप्चर किया था। बाद में उसी स्ट्रीम में ऑब्जेक्ट को कैप्चर करना थोड़ा तेज होगा।
यहाँ इस ताला के लिए बुनियादी सैद्धांतिक आवश्यकताएँ हैं:
- वस्तु के जीवन भर, यह मुख्य रूप से एक के स्वामित्व में है
- यदि थ्रेड ने हाल ही में इस ऑब्जेक्ट पर लॉक का उपयोग किया है, तो सबसे अधिक संभावना है कि प्रोसेसर कैश में अभी भी डेटा होगा जिसमें इस ऑब्जेक्ट को फिर से कैप्चर करने की आवश्यकता होगी।
जावा 6 के बाद से बायस्ड लॉकिंग डिफ़ॉल्ट रूप से सक्षम है: -UseBiasedLocking
- लॉक - इसमें लॉक स्टेटस कोड होता है। 00 - लाइटवेट लॉक, 01 - अनलॉक या बायस्ड, 10 - हैवीवेट लॉक, 11 - गारबेज कलेक्शन के लिए चिह्नित।
यही है, तालिका में, एक ऑब्जेक्ट की स्थिति को बायस्ड_लॉक और लॉक बिट्स के संयोजन से निर्धारित किया जाता है।
बायस्ड लॉक मोड (बायस्ड_लॉक = 1, लॉक = 01)
- धागा - पक्षपाती लॉकिंग मोड में, यह माना जाता है कि वस्तु मुख्य रूप से एक विशेष धागे के स्वामित्व में है, इस धागे की आईडी को क्षेत्र में संग्रहीत किया जाता है।
- युग में एक धागे द्वारा वस्तु के स्वामित्व के कुछ अस्थायी संकेतक होते हैं जिनकी आईडी धागे में संग्रहीत होती है
लाइटवेट लॉक मोड (लॉक = 00)
इस मोड में, यह माना जाता है कि अलग-अलग प्रवाह द्वारा इस ऑब्जेक्ट द्वारा कैप्चर का समय बिल्कुल भी अंतर नहीं करता है या नगण्य रूप से ओवरलैप नहीं करता है। इस मोड में, ऑपरेटिंग सिस्टम को भारी ब्लॉक करने के बजाय, जेवीएम एटमिक्स का उपयोग करता है।
- ptr_to_lock_record - स्पिन लूप के अंदर CAS (तुलना और सेट) का उपयोग लॉक को सेट / प्रतीक्षा करने के लिए किया जाता है।
संदर्भ के लिए, न्यूनतम ओएस अवरोधन समय लगभग 10 एमएस के क्षेत्र में होगा, एटमिक्स की मदद से, धारा सो नहीं जाती है, लेकिन एक छोटे से चक्र को थ्रेश करना जारी रखता है, और जैसे ही संसाधन मुक्त होता है, परमाणु चक्र समाप्त हो जाएगा और धारा तुरंत इस ऑब्जेक्ट को पकड़ लेगी।
हैवीवेट लॉक्ड मोड (लॉक = 10)
- ptr_to_heavyweight_monitor - यदि अलग-अलग धाराओं के साथ इस ऑब्जेक्ट का कैप्चर समय महत्वपूर्ण रूप से ओवरलैप होगा, तो लाइटवेट लॉक को हेवीवेट लॉक से बदल दिया जाएगा। मॉनिटर का एक पॉइंटर ptr_to_heavyweight_monitor को लिखा जाएगा। ओएस लॉक का उपयोग किया जाता है।
तो 32 बिट jvm में ऑब्जेक्ट के हेडर में 8 बाइट्स होते हैं। अतिरिक्त रूप से 4 बाइट्स होती हैं।
64 बिट jvm

64 बिट jvm पर, ऑब्जेक्ट हेडर में 16 बाइट्स होते हैं। अतिरिक्त रूप से 4 बाइट्स होती हैं।
सूचक संपीड़न के साथ 64 बिट jvm

ऑब्जेक्ट हेडर में 12 बाइट्स होते हैं। अतिरिक्त रूप से 4 बाइट्स होती हैं।
सूचक संपीड़न के बारे में थोड़ा सा। 32-बिट पॉइंटर के लिए, पता स्थान 4GB तक सीमित है। हालांकि, अगर हम फिर से याद करते हैं कि jvm में किसी ऑब्जेक्ट का आकार 8 बाइट्स से अधिक है, तो हम अंत में तीन शून्य के साथ एक छद्म 35-बिट पॉइंटर का उपयोग कर सकते हैं। और, इस प्रकार, पहले से ही 32GB मेमोरी का संदर्भ लें। संपीड़न मुक्त नहीं है, किसी भी कॉल को ढेर करने के लिए कीमत एक अतिरिक्त ऑपरेशन (पॉइंटर << 3) है।
मूल लेख का लिंक:
जावा ऑब्जेक्ट हैडर
मैं यह भी जोड़ना चाहूंगा कि यहां वर्णित सब कुछ एक हठधर्मिता नहीं है, शायद jvm के अन्य संस्करणों में वस्तु का शीर्षक अलग होगा। यहाँ बताया गया है कि Openjdk 8 के लिए प्रासंगिक है।