दोनों कार्यान्वयन के बीच बहुत समानताएं हैं (और मेरी राय में: हाँ, वे दोनों "वर्चुअल मशीन" हैं)।
एक बात के लिए, वे "रजिस्टर्स" की कोई धारणा नहीं रखते हैं, जैसे कि हम एक आधुनिक सीपीयू जैसे x86 या PowerPC में देखने के लिए उपयोग किए जाते हैं, दोनों स्टैक-आधारित वीएम हैं। सभी अभिव्यक्तियों का मूल्यांकन ((1 + 1)/2) ऑपरेंड को "स्टैक" पर दबाकर और फिर उन ऑपरेटरों को जोड़ने के लिए उन निर्देशों (एड, डिवाइड इत्यादि) की आवश्यकता होने पर स्टैप से बाहर निकलने के द्वारा किया जाता है। प्रत्येक निर्देश अपने परिणामों को वापस ढेर पर धक्का देता है।
वर्चुअल मशीन को लागू करने का यह एक सुविधाजनक तरीका है, क्योंकि दुनिया में हर सीपीयू में काफी ढेर होता है, लेकिन रजिस्टरों की संख्या अक्सर अलग होती है (और कुछ रजिस्ट्रार विशेष उद्देश्य होते हैं, और प्रत्येक निर्देश में इसके संचालन की अपेक्षा होती है विभिन्न रजिस्ट्रार, आदि)।
तो, यदि आप एक अमूर्त मशीन मॉडल करने जा रहे हैं, तो पूरी तरह से स्टैक-आधारित मॉडल जाने का एक बहुत अच्छा तरीका है।
बेशक, वास्तविक मशीनें इस तरह से संचालित नहीं होती हैं। तो जेआईटी कंपाइलर बाइटकोड संचालन के "पंजीकरण" करने के लिए ज़िम्मेदार है, अनिवार्य रूप से वास्तविक CPU रजिस्टरों को शेड्यूल करने के लिए समय-समय पर संचालन और परिणाम रखने के लिए शेड्यूल करना।
तो, मुझे लगता है कि यह सीएलआर और जेवीएम के बीच सबसे बड़ी समानताओं में से एक है।
अंतर के लिए के रूप में ...
एक दो कार्यान्वयन के बीच अंतर यह है कि दिलचस्प CLR उन प्रकार के लिए पैरामीट्रिक विशेषज्ञताओं को लागू करने के लिए सामान्य प्रकार बनाने के लिए निर्देश है, और फिर भी शामिल है। तो, रनटाइम पर, सीएलआर एक सूची <int> पर एक सूची < स्ट्रिंग > से एक पूरी तरह से अलग प्रकार होने के लिए एक सूची मानता है।
कवर के तहत, यह सब संदर्भ प्रकार विशेषज्ञताओं के लिए एक ही MSIL (ताकि एक सूची < स्ट्रिंग >, एक सूची < वस्तु > रूप में एक ही कार्यान्वयन का उपयोग करता विभिन्न प्रकार के साथ-डाले एपीआई सीमा पर) का उपयोग करता है, लेकिन हर मूल्य-प्रकार अपने स्वयं के अद्वितीय कार्यान्वयन का उपयोग करता है (सूची <int> सूची < डबल > से पूरी तरह से अलग कोड उत्पन्न करता है)।
जावा में, जेनेरिक प्रकार पूरी तरह से एक कंपाइलर चाल हैं। जेवीएम में कोई धारणा नहीं है कि किस वर्ग में टाइप-तर्क हैं, और यह रनटाइम पर पैरामीट्रिक विशेषज्ञता करने में असमर्थ है।
एक व्यावहारिक परिप्रेक्ष्य से, इसका मतलब है कि आप जेनेरिक प्रकारों पर जावा विधियों को अधिभारित नहीं कर सकते हैं। आपके पास एक ही नाम के साथ दो अलग-अलग विधियां नहीं हो सकती हैं, भले ही वे एक सूची < स्ट्रिंगया एक सूची < दिनांक > स्वीकार करें या नहीं। बेशक, चूंकि सीएलआर पैरामीट्रिक प्रकारों के बारे में जानता है, इसलिए सामान्य प्रकार की विशेषज्ञता पर ओवरलोड किए गए तरीकों को संभालने में कोई समस्या नहीं है।
दिन-दर-दिन आधार पर, यह अंतर है कि मैं सीएलआर और JVM के बीच सबसे अधिक ध्यान देता हूं।
अन्य महत्वपूर्ण अंतर में शामिल हैं:
CLR बंद (सी # प्रतिनिधियों के रूप में लागू) है। JVM केवल जावा 8.
CLR coroutines (सी # 'उपज' कीवर्ड के साथ लागू किया है) के बाद से समर्थन बंद नहीं करता है। जेवीएम नहीं करता है। जबकि JVM मूल्य प्रकार (बाइट, लघु, पूर्णांक, लंबे, नाव, डबल, चार, बुलियन) की एक निश्चित संग्रह प्रदान करता है और केवल उन की अनुमति देता है
CLR, उपयोगकर्ता कोड नया मान प्रकार (structs) को परिभाषित करने की अनुमति देता है नए संदर्भ-प्रकार (कक्षाएं) को परिभाषित करने के लिए।
CLR घोषित करने और संकेत जोड़ तोड़ के लिए सहायता प्रदान करता है। यह विशेष रूप से दिलचस्प है क्योंकि दोनों जेवीएम और सीएलआर कड़े कलेक्टर कार्यान्वयन कचरा कलेक्टर कार्यान्वयन को उनकी स्मृति प्रबंधन रणनीति के रूप में काम करते हैं। सामान्य परिस्थितियों में, सख्त कॉम्पैक्टिंग जीसी में पॉइंटर्स के साथ वास्तव में कठिन समय होता है, क्योंकि जब आप एक मेमोरी लोकेशन से दूसरे मान को ले जाते हैं, तो सभी पॉइंटर्स (और पॉइंटर्स टू पॉइंटर्स) अमान्य हो जाते हैं। लेकिन सीएलआर एक "पिनिंग" तंत्र प्रदान करता है ताकि डेवलपर्स कोड का एक ब्लॉक घोषित कर सकें जिसके अंतर्गत सीएलआर को कुछ पॉइंटर्स को स्थानांतरित करने की अनुमति नहीं है। यह बहुत सुविधाजनक है।
जेवीएम में कोड की सबसे बड़ी इकाई या तो 'संरक्षित' कीवर्ड द्वारा प्रमाणित एक 'पैकेज' है या तर्कसंगत रूप से एक जार (यानी जावा आर्किविव) है जैसा क्लासपाथ में एक जार निर्दिष्ट करने में सक्षम होने के प्रमाण के रूप में प्रमाणित है यह कोड के एक फ़ोल्डर की तरह व्यवहार किया। सीएलआर में, कक्षाओं को 'असेंबली' में एकत्रित किया जाता है, और सीएलआर असेंबली के बारे में तर्क और छेड़छाड़ के लिए तर्क प्रदान करता है (जो "ऐपडोमेन" में लोड होते हैं, स्मृति आवंटन और कोड निष्पादन के लिए उप-अनुप्रयोग-स्तर सैंडबॉक्स प्रदान करते हैं)।
CLR बाईटकोड प्रारूप (MSIL निर्देश और मेटाडाटा से बना) JVM की तुलना में कम अनुदेश प्रकार है। JVM में, प्रत्येक अद्वितीय ऑपरेशन (दो int मान जोड़ें, दो फ्लोट मान जोड़ें, आदि) का अपना अनूठा निर्देश है। सीएलआर में, सभी एमएसआईएल निर्देश पॉलिमॉर्फिक (दो मान जोड़ें) हैं और जेआईटी कंपाइलर ऑपरेटरों के प्रकारों को निर्धारित करने और उचित मशीन कोड बनाने के लिए ज़िम्मेदार है। मुझे नहीं पता कि अधिमानतः रणनीति कौन सा है। दोनों व्यापार-बंद हैं। JVM के लिए हॉटस्पॉट जेआईटी कंपाइलर, एक सरल कोड-जनरेशन तंत्र का उपयोग कर सकता है (इसे ऑपरेंड प्रकार निर्धारित करने की आवश्यकता नहीं है, क्योंकि वे पहले से ही निर्देश में एन्कोड किए गए हैं), लेकिन इसका मतलब है कि इसे अधिक जटिल बाइटकोड प्रारूप की आवश्यकता है, अधिक निर्देश प्रकार के साथ।
मैं लगभग दस वर्षों से जावा (और जेवीएम की प्रशंसा) का उपयोग कर रहा हूं।
लेकिन, मेरी राय में, सीएलआर अब लगभग हर तरह से बेहतर कार्यान्वयन है।
ठीक है, यदि आप की तरह तुलना कर रहे हैं, तो आपको वीएम और सीएलआर (कॉमन लैंग्वेज रनटाइम) के बीच का अंतर बता देना चाहिए, जो वीएम के प्रत्यक्ष अनुरूप हैं। – cletus
चेकआउट: [प्रबंधित मॉड्यूल में सीएलआर मेटाडाटा मिथक?] (Http://izlooite.blogspot.com/2009/09/what-is-clr-metadata-in-managed-module.html#more) –
@ ट्राउथ, आपने सवाल स्वयं से जुड़ा है .... –