2009-01-17 15 views
121

Differences between MSIL and Java bytecode? नामक प्रश्न के अनुवर्ती प्रकार के रूप में, जावा वर्चुअल मशीन कैसे काम करता है इस प्रकार (प्रमुख) अंतर या समानता क्या है .NET Framework सामान्य भाषा रनटाइम (सीएलआर) काम करता है?जावा की वर्चुअल मशीन और सीएलआर

इसके अलावा, .NET Framework सीएलआर एक "वर्चुअल मशीन" है या इसमें वर्चुअल मशीन के गुण नहीं हैं?

+0

ठीक है, यदि आप की तरह तुलना कर रहे हैं, तो आपको वीएम और सीएलआर (कॉमन लैंग्वेज रनटाइम) के बीच का अंतर बता देना चाहिए, जो वीएम के प्रत्यक्ष अनुरूप हैं। – cletus

+1

चेकआउट: [प्रबंधित मॉड्यूल में सीएलआर मेटाडाटा मिथक?] (Http://izlooite.blogspot.com/2009/09/what-is-clr-metadata-in-managed-module.html#more) –

+18

@ ट्राउथ, आपने सवाल स्वयं से जुड़ा है .... –

उत्तर

257

दोनों कार्यान्वयन के बीच बहुत समानताएं हैं (और मेरी राय में: हाँ, वे दोनों "वर्चुअल मशीन" हैं)।

एक बात के लिए, वे "रजिस्टर्स" की कोई धारणा नहीं रखते हैं, जैसे कि हम एक आधुनिक सीपीयू जैसे 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 के लिए हॉटस्पॉट जेआईटी कंपाइलर, एक सरल कोड-जनरेशन तंत्र का उपयोग कर सकता है (इसे ऑपरेंड प्रकार निर्धारित करने की आवश्यकता नहीं है, क्योंकि वे पहले से ही निर्देश में एन्कोड किए गए हैं), लेकिन इसका मतलब है कि इसे अधिक जटिल बाइटकोड प्रारूप की आवश्यकता है, अधिक निर्देश प्रकार के साथ।

मैं लगभग दस वर्षों से जावा (और जेवीएम की प्रशंसा) का उपयोग कर रहा हूं।

लेकिन, मेरी राय में, सीएलआर अब लगभग हर तरह से बेहतर कार्यान्वयन है।

+7

वाह। यह एक बेहतर तरीका है जितना मैंने कभी पूछा था। ईमानदारी से - धन्यवाद। –

+64

क्लोजर और जेनरेटर भाषा स्तर पर लागू किए जाते हैं और उन्हें सीएलआर स्तर पर कक्षाओं के रूप में दर्शाया जाता है। –

+1

ढेर को कैसे संभालने में अंतर के बारे में क्या? सीएलआर ओएस/होस्ट प्रो पर अधिक निर्भर है जबकि JVM ढेर मेमोरी को कम या ज्यादा पूरी तरह से प्रबंधित करता है। –

9

सीएलआर और जेवीएम वर्चुअल मशीन दोनों हैं।

.NET Framework और Java Runtime पर्यावरण संबंधित वीएम और उनके पुस्तकालयों का बंडल है। पुस्तकालयों के बिना वीएम बहुत बेकार हैं।

-11

यह एक आभासी मशीन नहीं है, .नेट फ्रेमवर्क पहली बार चलाने के समय में देशी बाइनरी में विधानसभाओं संकलित:

कंप्यूटिंग में, जस्ट-इन-समय संकलन (JIT), भी गतिशील के रूप में जाना अनुवाद, कंप्यूटर प्रोग्राम के रनटाइम प्रदर्शन को बेहतर बनाने के लिए एक तकनीक है। जेआईटी रन-टाइम वातावरण में दो पूर्व विचारों पर बनाता है: बाइटकोड संकलन और गतिशील संकलन। यह मूल रूप से निष्पादित करने से पहले रनटाइम पर कोड को परिवर्तित करता है, उदाहरण के लिए देशी मशीन कोड में बाइटकोड। दुभाषियों पर प्रदर्शन सुधार कोड के ब्लॉक का अनुवाद करने के परिणामों को कैशिंग करने से उत्पन्न होता है, और प्रत्येक बार जब यह पूरा हो जाता है तो प्रत्येक लाइन या ऑपरेंड का पुनर्मूल्यांकन नहीं करता है (व्याख्या की गई भाषा देखें)। इसके विकास के समय कोड को स्थिर रूप से संकलित करने के फायदे भी हैं, क्योंकि यदि यह फायदेमंद पाया जाता है तो यह कोड को पुन: संकलित कर सकता है, और सुरक्षा गारंटी लागू करने में सक्षम हो सकता है। इस प्रकार जेआईटी व्याख्या और स्थिर (आगे के समय) संकलन के कुछ फायदों को जोड़ सकता है।

कई आधुनिक रनटाइम वातावरण, जैसे माइक्रोसॉफ्ट के .NET Framework, जावा के अधिकांश कार्यान्वयन, और हाल ही में एक्शनस्क्रिप्ट 3, हाई स्पीड कोड निष्पादन के लिए जेआईटी संकलन पर भरोसा करते हैं।

स्रोत: http://en.wikipedia.org/wiki/Just-in-time_compilation

नेट फ्रेमवर्क शामिल करना और जावा की तरह, एक आभासी मशीन में शामिल है।

+10

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

24

आपका पहला प्रश्न जेवीएम की तुलना .NET Framework के साथ कर रहा है - मुझे लगता है कि आप वास्तव में सीएलआर के साथ तुलना करना चाहते थे। यदि हां, तो मुझे लगता है कि आप इस पर एक छोटे से पुस्तक (लिख सकता है संपादित करें: लग रहा है बेंजी पहले से ही है की तरह :-)

एक महत्वपूर्ण अंतर यह है कि CLR, एक भाषा-तटस्थ वास्तुकला डिज़ाइन किया गया है JVM के विपरीत है ।

एक और महत्वपूर्ण अंतर यह है कि सीएलआर विशेष रूप से मूल कोड के साथ उच्च स्तर की अंतःक्रियाशीलता की अनुमति देने के लिए डिज़ाइन किया गया था। इसका मतलब है कि सीएलआर-आधारित डेटा संरचनाओं और मूल डेटा संरचनाओं के बीच देशी मेमोरी का उपयोग और संशोधित होने पर सीएलआर को विश्वसनीयता और सुरक्षा का प्रबंधन करना चाहिए, और manage marshalling भी।

अपने दूसरे सवाल का जवाब करने के लिए, शब्द "आभासी मशीन" हार्डवेयर की दुनिया से एक बड़ा शब्द है (उदाहरण के लिए 1960 के दशक में 360 से आईबीएम के वर्चुअलाइजेशन) कि अंतर्निहित मशीन के एक सॉफ्टवेयर/हार्डवेयर अनुकरण मतलब था पूरा करने के लिए वही सामान जो VMWare करता है।

सीएलआर को अक्सर "निष्पादन इंजन" के रूप में जाना जाता है। इस संदर्भ में, यह एक x86 के शीर्ष पर एक आईएल मशीन का कार्यान्वयन है। यह भी जेवीएम करता है, हालांकि आप तर्क दे सकते हैं कि सीएलआर के पॉलीमोर्फिक बाइटकोड और जेवीएम के टाइप किए गए बाइटकोड्स के बीच एक महत्वपूर्ण अंतर है।

तो आपके दूसरे प्रश्न का pedantic उत्तर "नहीं" है। लेकिन यह वास्तव में नीचे आता है कि आप इन दो शर्तों को कैसे परिभाषित करते हैं।

संपादित करें: JVM और CLR के बीच एक और अंतर JVM (6 संस्करण) आबंटित स्मृति वापस ऑपरेटिंग सिस्टम के लिए जारी करने के लिए very reluctant है, यहां तक ​​कि जहां यह कर सकते हैं कि है।

उदाहरण के लिए, मान लीजिए कि एक जेवीएम प्रक्रिया प्रारंभ में ऑपरेटिंग सिस्टम से 25 एमबी मेमोरी शुरू होती है और आवंटित करती है। ऐप कोड तब आवंटन का प्रयास करता है जिसके लिए अतिरिक्त 50 एमबी की आवश्यकता होती है। जेवीएम ऑपरेटिंग सिस्टम से अतिरिक्त 50 एमबी आवंटित करेगा। एक बार जब एप्लिकेशन कोड उस स्मृति का उपयोग बंद कर देता है, तो यह कचरा इकट्ठा होता है और जेवीएम ढेर का आकार घट जाएगा। हालांकि, JVM केवल very specific circumstances के तहत आवंटित ऑपरेटिंग सिस्टम मेमोरी को मुक्त करेगा। अन्यथा, शेष प्रक्रिया के जीवनकाल के लिए स्मृति आवंटित रहेगी।

दूसरी ओर, सीएलआर आवंटित स्मृति को ऑपरेटिंग सिस्टम पर वापस जारी करता है यदि इसकी आवश्यकता नहीं है। ऊपर दिए गए उदाहरण में, ढेर कम होने के बाद सीएलआर स्मृति को जारी कर देता।

+1

फिट लगता है यह पूर्णतया सही नहीं है कि JVM आवंटित स्मृति मुक्त नहीं करेगा। सबूत के लिए इस प्रश्न का मेरा उत्तर देखें: http://stackoverflow.com/questions/366658/java-6-excessive-memory-usage#367933 –

+0

मैंने जेवीएम रिटर्न मेमोरी को विंडोज़ में वापस देखा है। –

+0

मैंने अपना जवाब यह कहने के लिए बदल दिया है कि जेवीएम 6 रण और माइकल के उत्तरों के लिंक के साथ मेमोरी रिलीज करने में बहुत अनिच्छुक है। मैंने इस व्यवहार को JVM 5 के साथ कभी नहीं देखा, तो हो सकता है कि वह संस्करण और भी अनिच्छुक था। – RoadWarrior

9

मतभेदों पर अधिक विशिष्टता विभिन्न अकादमिक और निजी स्रोतों से मिल सकती है। एक बार अच्छा उदाहरण CLR Design Choices है।

कुछ विशिष्ट उदाहरण में शामिल हैं:

  • कुछ निम्न स्तर के opperands रूप में इस तरह लिखे जाते हैं, जहां के रूप में CLR एक बहुरूपी संकार्य का उपयोग करता है "दो ints जोड़ें"। (यानी fadd/iadd/ladd बनाम बस जोड़ें)
  • वर्तमान में, JVM अधिक आक्रामक रनटाइम प्रोफाइलिंग और अनुकूलन (यानी हॉटस्पॉट) करता है। सीएलआर वर्तमान में जेआईटी अनुकूलन करता है, लेकिन रनटाइम अनुकूलन नहीं (यानी जब आप चल रहे हों तो कोड को प्रतिस्थापित करें)।
  • सीएलआर आभासी तरीकों को रेखांकित नहीं करता है, जेवीएम करता है ...
  • सीएलआर में मूल्य "प्राइमेटिव्स" से परे मूल्य प्रकारों के लिए समर्थन।
संबंधित मुद्दे