मेमोरी हार्डवेयर आर्किटेक्चर

आधुनिक मेमोरी हार्डवेयर आर्किटेक्चर जावा के इंटरनल मेमोरी मॉडल से अलग है। इसलिए, जावा मॉडल इसके साथ कैसे काम करता है, यह जानने के लिए आपको हार्डवेयर आर्किटेक्चर को समझने की आवश्यकता है। यह खंड सामान्य मेमोरी हार्डवेयर आर्किटेक्चर का वर्णन करता है, और अगला खंड वर्णन करता है कि जावा इसके साथ कैसे काम करता है।

यहाँ एक आधुनिक कंप्यूटर के हार्डवेयर आर्किटेक्चर का एक सरल आरेख है:

मेमोरी हार्डवेयर आर्किटेक्चर

आधुनिक दुनिया में, कंप्यूटर में 2 या अधिक प्रोसेसर होते हैं और यह पहले से ही आदर्श है। इनमें से कुछ प्रोसेसर में कई कोर भी हो सकते हैं। ऐसे कंप्यूटरों पर एक ही समय में कई थ्रेड चलाना संभव है। प्रत्येक प्रोसेसर कोर किसी भी समय एक थ्रेड को निष्पादित करने में सक्षम होता है। इसका मतलब यह है कि कोई भी जावा एप्लिकेशन एक प्राथमिक बहु-थ्रेडेड है, और आपके प्रोग्राम के भीतर, एक थ्रेड प्रति प्रोसेसर कोर एक समय में चल सकता है।

प्रोसेसर कोर में रजिस्टरों का एक सेट होता है जो इसकी मेमोरी (कोर के अंदर) में रहता है। यह कंप्यूटर की मुख्य मेमोरी (RAM) में मौजूद डेटा की तुलना में रजिस्टर डेटा पर बहुत तेजी से संचालन करता है। ऐसा इसलिए है क्योंकि प्रोसेसर इन रजिस्टरों को बहुत तेजी से एक्सेस कर सकता है।

प्रत्येक CPU की अपनी कैश परत भी हो सकती है। अधिकांश आधुनिक प्रोसेसर में यह है। प्रोसेसर अपने कैश को मुख्य मेमोरी की तुलना में बहुत तेजी से एक्सेस कर सकता है, लेकिन उतनी तेजी से नहीं जितना कि इसके आंतरिक रजिस्टर। कैश एक्सेस गति का मान लगभग मुख्य मेमोरी और आंतरिक रजिस्टरों की एक्सेस गति के बीच होता है।

इसके अलावा, प्रोसेसर के पास बहु-स्तरीय कैश रखने की जगह होती है। लेकिन जावा मेमोरी मॉडल हार्डवेयर मेमोरी के साथ कैसे इंटरैक्ट करता है, यह समझने के लिए यह जानना इतना महत्वपूर्ण नहीं है। यह जानना महत्वपूर्ण है कि प्रोसेसर में कैश का कुछ स्तर हो सकता है।

किसी भी कंप्यूटर में उसी तरह रैम (मुख्य मेमोरी एरिया) भी होता है। सभी कोर मुख्य मेमोरी तक पहुंच सकते हैं। मुख्य मेमोरी क्षेत्र आमतौर पर प्रोसेसर कोर की कैश मेमोरी से काफी बड़ा होता है।

उस समय जब प्रोसेसर को मुख्य मेमोरी तक पहुंच की आवश्यकता होती है, वह इसका हिस्सा अपनी कैश मेमोरी में पढ़ता है। यह कैश से कुछ डेटा को अपने आंतरिक रजिस्टरों में भी पढ़ सकता है और फिर उन पर कार्रवाई कर सकता है। जब सीपीयू को परिणाम को वापस मुख्य मेमोरी में लिखने की आवश्यकता होती है, तो यह डेटा को अपने आंतरिक रजिस्टर से कैश में और कुछ बिंदु पर मुख्य मेमोरी में फ्लश कर देगा।

जब प्रोसेसर को कैश में कुछ और स्टोर करने की आवश्यकता होती है तो कैश में संग्रहीत डेटा सामान्य रूप से मुख्य मेमोरी में वापस आ जाता है। कैश में एक ही समय में अपनी मेमोरी साफ़ करने और डेटा लिखने की क्षमता होती है। अद्यतन के दौरान प्रोसेसर को हर बार पूर्ण कैश को पढ़ने या लिखने की आवश्यकता नहीं होती है। आमतौर पर कैश को मेमोरी के छोटे ब्लॉक में अपडेट किया जाता है, उन्हें "कैश लाइन" कहा जाता है। एक या अधिक "कैश लाइन" को कैश मेमोरी में पढ़ा जा सकता है, और एक या अधिक कैश लाइन को मुख्य मेमोरी में वापस फ़्लश किया जा सकता है।

जावा मेमोरी मॉडल और मेमोरी हार्डवेयर आर्किटेक्चर का संयोजन

जैसा कि पहले ही उल्लेख किया गया है, जावा मेमोरी मॉडल और मेमोरी हार्डवेयर आर्किटेक्चर अलग-अलग हैं। हार्डवेयर आर्किटेक्चर थ्रेड स्टैक और ढेर के बीच अंतर नहीं करता है। हार्डवेयर पर, थ्रेड स्टैक और HEAP (हीप) मुख्य मेमोरी में रहते हैं।

स्टैक और थ्रेड हीप के हिस्से कभी-कभी कैश और सीपीयू के आंतरिक रजिस्टरों में मौजूद हो सकते हैं। यह आरेख में दिखाया गया है:

थ्रेड स्टैक और HEAP

जब ऑब्जेक्ट्स और वेरिएबल्स को कंप्यूटर की मेमोरी के विभिन्न क्षेत्रों में संग्रहीत किया जा सकता है, तो कुछ समस्याएं उत्पन्न हो सकती हैं। यहाँ दो मुख्य हैं:

  • थ्रेड द्वारा शेयर किए गए वेरिएबल में किए गए परिवर्तनों की दृश्यता।
  • साझा चर पढ़ने, जाँचने और लिखने पर दौड़ की स्थिति।

इन दोनों मुद्दों को नीचे समझाया जाएगा।

साझा वस्तुओं की दृश्यता

यदि दो या दो से अधिक थ्रेड अस्थिर घोषणा या सिंक्रनाइज़ेशन के उचित उपयोग के बिना किसी ऑब्जेक्ट को साझा करते हैं, तो एक थ्रेड द्वारा साझा की गई वस्तु में किए गए परिवर्तन अन्य थ्रेड्स के लिए दृश्यमान नहीं हो सकते हैं।

कल्पना कीजिए कि एक साझा वस्तु प्रारंभ में मुख्य स्मृति में संग्रहीत होती है। सीपीयू पर चलने वाला थ्रेड साझा किए गए ऑब्जेक्ट को उसी सीपीयू के कैश में पढ़ता है। वहां वह वस्तु में परिवर्तन करता है। जब तक सीपीयू के कैश को मुख्य मेमोरी में फ्लश नहीं किया जाता है, तब तक साझा किए गए ऑब्जेक्ट का संशोधित संस्करण अन्य सीपीयू पर चलने वाले थ्रेड्स के लिए दृश्यमान नहीं होता है। इस प्रकार, प्रत्येक थ्रेड साझा वस्तु की अपनी प्रति प्राप्त कर सकता है, प्रत्येक प्रति एक अलग CPU कैश में होगी।

निम्नलिखित आरेख इस स्थिति की रूपरेखा दिखाता है। बाएँ CPU पर चलने वाला एक थ्रेड साझा ऑब्जेक्ट को अपने कैश में कॉपी करता है और गिनती के मान को 2 में बदल देता है। यह परिवर्तन दाएं CPU पर चल रहे अन्य थ्रेड्स के लिए अदृश्य है क्योंकि काउंट करने के लिए अपडेट अभी तक मुख्य मेमोरी में वापस नहीं किया गया है।

इस समस्या को हल करने के लिए, आप चर घोषित करते समय अस्थिर कीवर्ड का उपयोग कर सकते हैं। यह सुनिश्चित कर सकता है कि किसी दिए गए चर को मुख्य मेमोरी से सीधे पढ़ा जाता है और अद्यतन किए जाने पर हमेशा मुख्य मेमोरी में वापस लिखा जाता है।

दौड़ की स्थिति

यदि दो या अधिक थ्रेड एक ही ऑब्जेक्ट साझा करते हैं और एक से अधिक थ्रेड उस साझा ऑब्जेक्ट में वेरिएबल अपडेट करते हैं, तो दौड़ की स्थिति हो सकती है।

कल्पना करें कि थ्रेड ए साझा ऑब्जेक्ट के गिनती चर को अपने प्रोसेसर के कैश में पढ़ता है। यह भी कल्पना करें कि थ्रेड बी वही काम करता है, लेकिन दूसरे प्रोसेसर के कैश में। अब थ्रेड ए गिनती के मान में 1 जोड़ता है, और थ्रेड बी वही करता है। अब वेरिएबल को दो बार बढ़ा दिया गया है - प्रत्येक प्रोसेसर के कैश में +1 द्वारा अलग से।

यदि ये वृद्धि क्रमिक रूप से की जाती है, तो गणना चर को दोगुना कर दिया जाएगा और मुख्य मेमोरी (मूल मान + 2) पर वापस लिखा जाएगा।

हालाँकि, दो वेतन वृद्धि एक ही समय में उचित सिंक्रनाइज़ेशन के बिना की गई थी। कोई फर्क नहीं पड़ता कि कौन सा थ्रेड (ए या बी) गिनती के अपने अद्यतन संस्करण को मुख्य मेमोरी में लिखता है, दो वेतन वृद्धि के बावजूद नया मान मूल मान से केवल 1 अधिक होगा।

यह आरेख ऊपर वर्णित दौड़ स्थिति समस्या की घटना को दर्शाता है:

इस समस्या को हल करने के लिए, आप जावा सिंक्रोनाइज़्ड ब्लॉक का उपयोग कर सकते हैं। एक सिंक्रनाइज़ ब्लॉक यह सुनिश्चित करता है कि किसी भी समय केवल एक धागा कोड के दिए गए महत्वपूर्ण खंड में प्रवेश कर सकता है।

सिंक्रोनाइज़्ड ब्लॉक यह भी गारंटी देते हैं कि सिंक्रोनाइज़्ड ब्लॉक के अंदर एक्सेस किए गए सभी वेरिएबल्स को मेन मेमोरी से पढ़ा जाएगा, और जब थ्रेड सिंक्रोनाइज़्ड ब्लॉक से बाहर निकलता है, तो सभी अपडेटेड वेरिएबल्स को मुख्य मेमोरी में वापस फ़्लश कर दिया जाएगा, भले ही वेरिएबल को अस्थिर घोषित किया गया हो या नहीं।