जावा बाइटकोड को स्रोत कोड परिवर्तित करने का क्या उपयोग है?


37

अगर किसी को अलग-अलग आर्किटेक्चर के लिए अलग-अलग जेवीएम की जरूरत है तो मैं यह पता नहीं लगा सकता कि इस अवधारणा को शुरू करने के पीछे क्या तर्क है। अन्य भाषाओं में हमें अलग-अलग मशीनों के लिए अलग-अलग कंपाइलर की आवश्यकता होती है, लेकिन जावा में हमें अलग-अलग JVM की आवश्यकता होती है, इसलिए JVM या इस अतिरिक्त कदम की अवधारणा को शुरू करने के पीछे तर्क क्या है ??


1
संकलित करने की संभावित डुप्लिकेट बाइटेकोड बनाम मशीन कोड
gnat

12
@gnat: दरअसल, यह कोई डुप्लिकेट नहीं है। यह "स्रोत बनाम बाइट कोड" है, अर्थात केवल पहला परिवर्तन। भाषा के संदर्भ में, यह जावास्क्रिप्ट बनाम जावा है; आपका लिंक C ++ बनाम जावा होगा।
मैटलर्स

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

1
आपको यह समझ नहीं आ रहा है कि वर्चुअल मशीन क्या है । इसकी एक मशीन है। इसे देशी-कोड संकलक (और जेवीएम के मामले में) के साथ हार्डवेयर में लागू किया जा सकता है। यहां 'वर्चुअल' हिस्सा महत्वपूर्ण है: आप अनिवार्य रूप से उस वास्तुकला को दूसरे के शीर्ष पर अनुकरण कर रहे हैं । मान लीजिए कि मैंने x86 पर चलने के लिए 8088 एमुलेटर लिखा है। आप पुराने 8088 कोड को x86 में पोर्ट नहीं करने जा रहे हैं, आप इसे केवल एम्युलेटेड प्लेटफॉर्म पर चलाने जा रहे हैं। JVM एक मशीन है जिसे आप किसी भी अन्य की तरह लक्षित करते हैं, यह अंतर अन्य प्लेटफार्मों के शीर्ष पर चलता है।
जेरेड स्मिथ

7
@ GreatDuck इंटरप्रेटिंग प्रक्रिया? आजकल ज्यादातर JVM मशीन कोड के लिए समय-समय पर संकलन करते हैं। उल्लेख नहीं है कि "व्याख्या" आजकल एक बहुत व्यापक शब्द है। CPU स्वयं ही x86 कोड को अपने आंतरिक माइक्रोकोड में "व्याख्या" करता है, और इसका उपयोग दक्षता में सुधार करने के लिए किया जाता है । नवीनतम इंटेल सीपीयू सामान्य रूप से दुभाषियों के लिए बहुत अच्छी तरह से अनुकूल हैं (हालांकि आप जो भी साबित करना चाहते हैं उसे साबित करने के लिए बेंचमार्क पाएंगे)।
लुआण

जवाबों:


79

तर्क यह है कि जावा स्रोत कोड की तुलना में जेवीएम बायटेकोड बहुत सरल है।

कंप्रेशर्स के बारे में सोचा जा सकता है, एक उच्च अमूर्त स्तर पर, तीन बुनियादी भागों के रूप में: पार्सिंग, अर्थ विश्लेषण और कोड पीढ़ी।

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

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

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


7
एप्लेट वितरण में कुछ अन्य शुरुआती प्रयास, जैसे कि SafeTCL, ने वास्तव में स्रोत कोड वितरित किया था। जावा का एक सरल और कसकर निर्दिष्ट बायटेकोड का उपयोग कार्यक्रम के सत्यापन को और अधिक सुगम बनाता है , और यह कठिन समस्या थी जिसे हल किया जा रहा था। पी-कोड जैसे बाइटकोड्स को पोर्टेबिलिटी समस्या के समाधान के हिस्से के रूप में पहले से ही जाना जाता था (और ANDF शायद उस समय विकास में था)।
टोबे स्पीट

9
ठीक। जावा स्टार्ट अप बार पहले से ही एक समस्या का एक सा है क्योंकि बाइटकोड -> मशीन कोड चरण। अपने (गैर-तुच्छ) प्रोजेक्ट पर javac चलाएं, और फिर हर स्टार्ट अप पर उस पूरे जावा -> मशीन कोड को करने की कल्पना करें।
पॉल ड्रेपर

24
इसका एक अन्य बहुत बड़ा लाभ है: यदि किसी दिन हम सभी एक काल्पनिक नई भाषा पर स्विच करना चाहते हैं - चलो इसे "स्काला" कहते हैं - हमें केवल एक स्काला लिखने की आवश्यकता है -> दर्जनों स्काला के बजाय -> स्कैटेकोड संकलक -> compilers। एक बोनस के रूप में, हमें जेवीएम के सभी प्लेटफॉर्म-विशिष्ट अनुकूलन मुफ्त में मिलते हैं।
ब्लूराजा - डैनी पफ्लुगुएफ्ट

8
जेवीएम बाइट कोड में कुछ चीजें अभी भी संभव नहीं हैं, जैसे टेल कॉल ऑप्टिमाइज़ेशन। मुझे याद है कि यह एक कार्यात्मक भाषा है जो JVM के लिए संकलित है।
JDługosz

8
@ JDługosz सही: JVM दुर्भाग्य से कुछ प्रतिबंधों / डिजाइन मुहावरों को लगाता है, जबकि वे पूरी तरह से स्वाभाविक हो सकते हैं यदि आप एक अनिवार्य भाषा से आ रहे हैं, तो आप एक कृत्रिम अवरोधक बन सकते हैं यदि आप एक भाषा के लिए एक कंपाइलर लिखना चाहते हैं जो मौलिक रूप से काम करता है विभिन्न। मैं इस प्रकार एलएलवीएम को एक बेहतर लक्ष्य मानता हूं, जहां तक ​​भविष्य की भाषा-काम-पुन: उपयोग का सवाल है - इसकी सीमाएँ भी हैं, लेकिन वे कम या ज्यादा उन सीमाओं से मेल खाते हैं जो वर्तमान (और भविष्य में कुछ समय) प्रोसेसर के वैसे भी हैं।
लेफ्टरनैबाउट

27

विभिन्न कारणों से इंटरमीडिएट अभ्यावेदन कुछ कारणों से कंपाइलर / रनटाइम डिज़ाइन में आम हैं।

जावा के मामले में, शुरू में नंबर एक कारण संभवतः पोर्टेबिलिटी था: जावा को शुरुआत में "राइट वन्स, रन एनीवेयर" के रूप में शुरू में विपणन किया गया था। जब आप स्रोत कोड को वितरित करके और विभिन्न प्लेटफार्मों को लक्षित करने के लिए विभिन्न कंपाइलरों का उपयोग करके इसे प्राप्त कर सकते हैं, तो इसमें कुछ डाउनसाइड हैं:

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

मध्यवर्ती प्रतिनिधित्व के अन्य लाभों में शामिल हैं:

  • अनुकूलन , जहां पैटर्न को बाइटकोड में देखा जा सकता है और तेज समकक्षों के लिए संकलित किया जा सकता है, या विशेष मामलों के लिए भी अनुकूलित किया जा सकता है क्योंकि कार्यक्रम चलता है ("जेआईटी", या "जस्ट इन टाइम", संकलक का उपयोग करके)
  • एक ही वीएम में कई भाषाओं के बीच अंतर ; यह JVM (जैसे स्काला) के साथ लोकप्रिय हो गया है, और .net फ्रेमवर्क का स्पष्ट उद्देश्य है

1
जावा एम्बेडेड सिस्टम के लिए भी उन्मुख था। ऐसी प्रणालियों में, हार्डवेयर में मेमोरी और सीपीयू की कई अड़चनें थीं।
लाईव

क्या कंपेलर्स को इस तरह से विकसित किया जा सकता है कि वे पहले जावा सोर्स कोड को बाइट कोड में संकलित करें और फिर बाइट कोड को मशीन कोड में संकलित करें? क्या यह आपके द्वारा उल्लिखित अधिकांश डाउनसाइड को खत्म कर देगा?
शेर १०

@ Sher10ck हाँ, यह पूरी तरह से संभव है AFAIK एक संकलक को लिखने के लिए जो किसी विशेष वास्तुकला के लिए मशीन के निर्देशों के लिए जेवीएम बायटेकोड को रूपांतरित करता है। लेकिन यह केवल तभी समझ में आता है जब इससे प्रदर्शन में सुधार होता है या तो वितरक के लिए अतिरिक्त प्रयास, या उपयोगकर्ता के लिए पहली बार उपयोग करने का अतिरिक्त समय। एक कम-शक्ति एम्बेडेड सिस्टम को लाभ हो सकता है; एक आधुनिक पीसी डाउनलोड करना और कई अलग-अलग प्रोग्राम चलाना संभवतः एक अच्छी तरह से ट्यून किए गए JIT के साथ बेहतर होगा। मुझे लगता है कि एंड्रॉइड इस दिशा में कहीं जाता है, लेकिन विवरण नहीं जानता।
IMSoP

8

ऐसा लगता है कि आप सोच रहे हैं कि हम केवल स्रोत कोड क्यों नहीं वितरित करते हैं। मुझे उस प्रश्न को चारों ओर मोड़ने दें: हम सिर्फ मशीन कोड क्यों नहीं वितरित करते हैं?

यहाँ स्पष्ट रूप से उत्तर यह है कि जावा, डिज़ाइन द्वारा, यह नहीं मानता है कि यह पता है कि मशीन क्या है जहां आपका कोड चलेगा; यह एक डेस्कटॉप, एक सुपर-कंप्यूटर, एक फोन या बीच में और उससे आगे कुछ भी हो सकता है। जावा स्थानीय जेवीएम संकलक के लिए अपना काम करने के लिए कमरा छोड़ देता है। अपने कोड की पोर्टेबिलिटी बढ़ाने के अलावा, इससे कंपाइलर को मशीन-विशिष्ट ऑप्टिमाइज़ेशन का लाभ उठाने जैसे काम करने की अनुमति देने का अच्छा लाभ होता है, यदि वे मौजूद हैं, या अभी भी कम से कम काम करने वाले कोड का उत्पादन करते हैं यदि वे नहीं करते हैं। SSE निर्देश या हार्डवेयर त्वरण जैसी चीजें केवल उन मशीनों पर उपयोग की जा सकती हैं जो उनका समर्थन करती हैं।

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

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

ध्यान दें कि मैं तेजी से निष्पादन का उल्लेख नहीं करता हूं। स्रोत कोड और बाइट कोड दोनों वास्तविक निष्पादन के लिए एक ही मशीन कोड के लिए पूरी तरह से संकलित (या सिद्धांत में) हो सकते हैं।

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


8

यहां कम से कम दो अलग-अलग संभावित प्रश्न प्रतीत होते हैं। एक वास्तव में संकलक के बारे में है, जावा मूल रूप से शैली का एक उदाहरण है। अन्य जावा के लिए विशिष्ट विशिष्ट बाइट कोड है जो इसका उपयोग करता है।

सामान्य रूप से संकलक

आइए पहले सामान्य प्रश्न पर विचार करें: किसी विशेष प्रोसेसर पर चलने के लिए संकलक स्रोत कोड की प्रक्रिया में एक संकलक कुछ मध्यवर्ती प्रतिनिधित्व का उपयोग क्यों करेगा?

जटिलता में कमी

इसका एक उत्तर काफी सरल है: यह एक O (N * M) समस्या को O (N + M) समस्या में परिवर्तित करता है।

यदि हमें N स्रोत भाषाएं, और M लक्ष्य दिए गए हैं, और प्रत्येक संकलक पूरी तरह से स्वतंत्र है, तो हमें N * M संकलक की आवश्यकता है उन सभी स्रोत भाषाओं को उन सभी लक्ष्यों (जहाँ "लक्ष्य" कुछ के संयोजन की तरह है) प्रोसेसर और ओएस)।

यदि, हालांकि, वे सभी कंपाइलर एक सामान्य मध्यवर्ती प्रतिनिधित्व पर सहमत हैं, तो हमारे पास एन कंपाइलर फ्रंट एंड्स हो सकते हैं जो स्रोत भाषाओं को मध्यवर्ती प्रतिनिधित्व में अनुवाद करते हैं, और एम कंपाइलर बैक एंड्स जो किसी विशिष्ट लक्ष्य के लिए उपयुक्त कुछ के लिए मध्यवर्ती प्रतिनिधित्व का अनुवाद करते हैं।

समस्या विभाजन

बेहतर अभी भी, यह समस्या को दो या अधिक अनन्य डोमेन में अलग करता है। जो लोग भाषा डिजाइन, पार्सिंग और उस तरह की चीजों के बारे में जानते हैं, वे संकलक सामने के छोर पर ध्यान केंद्रित कर सकते हैं, जबकि लोग जो निर्देश सेट, प्रोसेसर डिजाइन और इस तरह की चीजों के बारे में जानते हैं, वे पीछे के छोर पर ध्यान केंद्रित कर सकते हैं।

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

संकलक को फ्रंट एंड बैक एंड में अलग करना, एक मध्यवर्ती प्रतिनिधित्व के साथ दोनों के बीच संवाद जावा के साथ मूल नहीं है। यह लंबे समय से सामान्य व्यवहार रहा है (चूंकि जावा के साथ आने से पहले, वैसे भी)।

वितरण मॉडल

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

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

उदाहरण

ध्यान दें कि यह वितरण मॉडल पूरी तरह से नया भी नहीं था। उदाहरण के लिए, यूसीएसडी पी-सिस्टम ने समान रूप से काम किया: कंपाइलर फ्रंट एंड ने पी-कोड का उत्पादन किया, और पी-सिस्टम की प्रत्येक कॉपी में एक वर्चुअल मशीन शामिल थी जो उस विशेष लक्ष्य 1 पर पी-कोड को निष्पादित करने के लिए आवश्यक थी ।

जावा बाइट-कोड

जावा बाइट कोड पी-कोड से काफी मिलता-जुलता है। यह मूल रूप से काफी सरल मशीन के लिए निर्देश है । उस मशीन को मौजूदा मशीनों के अमूर्त होने का इरादा है, इसलिए लगभग किसी भी विशिष्ट लक्ष्य के लिए जल्दी से अनुवाद करना काफी आसान है। अनुवाद में आसानी जल्दी थी क्योंकि मूल इरादा बाइट कोड की व्याख्या करना था, जैसे कि पी-सिस्टम ने किया था (और, हां, यह ठीक है कि शुरुआती कार्यान्वयन कैसे काम किया गया)।

ताकत

एक कंपाइलर फ्रंट-एंड के लिए जावा बाइट कोड आसान है। यदि (उदाहरण के लिए) आपके पास एक बहुत ही विशिष्ट पेड़ है जो एक अभिव्यक्ति का प्रतिनिधित्व करता है तो यह आम तौर पर पेड़ को पार करने के लिए बहुत आसान होता है, और प्रत्येक नोड पर आपको जो भी मिलता है उससे सीधे कोड उत्पन्न करता है।

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

कमजोरियों

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

उदाहरण के लिए, यह बहुत नियमित है कि यदि आप वास्तव में जावा बाइट कोड का अनुकूलन करना चाहते हैं, तो आप मूल रूप से प्रतिनिधित्व की तरह मशीन-कोड से उन्हें पीछे की ओर ट्रांसलेट करने के लिए कुछ रिवर्स इंजीनियरिंग करते हैं, और उन्हें एसएसए निर्देशों (या कुछ इसी तरह) 2 में बदल देते हैं । फिर आप अपने अनुकूलन को करने के लिए SSA के निर्देशों में फेरबदल करते हैं, फिर वहाँ से किसी ऐसी चीज़ का अनुवाद करते हैं जो उस वास्तुकला को लक्षित करती है जिसकी आप वास्तव में परवाह करते हैं। यहां तक ​​कि इस जटिल प्रक्रिया के साथ, हालांकि, कुछ अवधारणाएं जो जावा के लिए विदेशी हैं, यह व्यक्त करना पर्याप्त रूप से कठिन है कि कुछ स्रोत भाषाओं से मशीन कोड में अनुवाद करना मुश्किल है, जो कि (यहां तक ​​कि लगभग) सबसे विशिष्ट मशीनों पर भी चलता है।

सारांश

यदि आप सामान्य रूप से मध्यवर्ती अभ्यावेदन का उपयोग करने के बारे में पूछ रहे हैं, तो दो प्रमुख कारक हैं:

  1. एक O (N + M) समस्या को O (N * M) समस्या को कम करें, और
  2. समस्या को अधिक प्रबंधनीय टुकड़ों में तोड़ दें।

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

  1. कॉम्पैक्ट प्रतिनिधित्व।
  2. त्वरित और डिकोड और निष्पादित करने में आसान।
  3. सबसे आम मशीनों पर लागू करने के लिए त्वरित और आसान।

कई भाषाओं का प्रतिनिधित्व करने में सक्षम होने या व्यापक रूप से विभिन्न प्रकार के लक्ष्यों पर अमल करने की प्राथमिकताएँ बहुत कम थीं (यदि उन्हें प्राथमिकताएँ माना जाता था)।


  1. तो पी-सिस्टम को ज्यादातर क्यों भुला दिया जाता है? ज्यादातर एक मूल्य निर्धारण की स्थिति। पी-सिस्टम ने Apple II, Commodore SuperPets, आदि पर काफी शालीनता से बिक्री की, जब IBM PC बाहर आया, P- सिस्टम एक समर्थित OS था, लेकिन MS-DOS की लागत कम थी (ज्यादातर लोगों के दृष्टिकोण से, अनिवार्य रूप से मुफ्त में फेंक दिया गया था) जल्दी से अधिक कार्यक्रम उपलब्ध थे, क्योंकि यह माइक्रोसॉफ्ट और आईबीएम (दूसरों के बीच) के लिए क्या लिखा था।
  2. उदाहरण के लिए, यह कैसे है कालिख काम करता है।

वेब एप्लेट्स के साथ काफी करीब: मूल इरादा उपकरणों को कोड वितरित करना था (शीर्ष बॉक्स ...), उसी तरह जिस तरह RPC फ़ंक्शन कॉल वितरित करता है, और CORBA ऑब्जेक्ट वितरित करता है।
नवजलज

2
यह एक महान जवाब है, और विभिन्न मध्यवर्ती प्रतिनिधित्व अलग-अलग व्यापारों को कैसे बनाते हैं, इस बारे में एक अच्छी जानकारी है। :)
IMSoP

@ ननजालज: वह सचमुच ओक था। जब तक यह जावा में जोड़ दिया गया था, मेरा मानना ​​है कि सेट टॉप बॉक्स (और इसी तरह) विचारों को आश्रय दिया गया था (हालांकि मैं मानता हूं कि ओक और जावा एक ही बात करने के लिए एक उचित तर्क है)।
जेरी कॉफ़िन

@ टिप्पणी: हाँ, अभिव्यक्ति शायद वहाँ एक बेहतर फिट है। धन्यवाद।
जेरी कॉफ़िन

0

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

इससे कॉपीराइट स्रोत कोड की सुरक्षा करना भी आसान हो जाता है।


2
जावा (और .NET) बाईटेकोड इतना सुपाठ्य स्रोत में वापस मोड़ना इतना आसान है कि इस मुश्किल को आसान बनाने के लिए नाम और कभी-कभी अन्य जानकारी देने के लिए उत्पाद होते हैं - कुछ ऐसा जो अक्सर जावास्क्रिप्ट के लिए किया जाता है, क्योंकि हम अभी हैं। हो सकता है कि वेब ब्राउज़र के लिए एक बायोटेक पर सेटिंग हो।
LnxPrgr3

0

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


0

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

केवल बाद में, जब यह स्पष्ट हुआ कि जेवीएम की व्याख्या करने वाला प्रदर्शन अभी भी बेकार है, क्या लोगों ने अच्छी तरह से प्रदर्शन करने वाले समय-संकलक बनाने के प्रयास का निवेश किया था। इसने सी और सी ++ जैसी तेज भाषाओं के अंतर को बंद कर दिया। (कुछ जावा अंतर्निहित गति के मुद्दे बने हुए हैं, हालांकि, आपको शायद एक जावा वातावरण कभी नहीं मिलेगा जो प्रदर्शन के साथ-साथ सी कोड भी लिखता है।)

बेशक, हाथ में सिर्फ-समय संकलन तकनीकों के साथ, हम वास्तव में स्रोत कोड वितरित करने के लिए वापस जा सकते हैं, और बस-समय-समय पर इसे मशीन कोड में संकलित कर रहे हैं। हालाँकि, इससे स्टार्टअप प्रदर्शन में भारी कमी आएगी जब तक कि कोड के सभी प्रासंगिक भागों को संकलित नहीं किया जाता है। बाइट कोड अभी भी यहाँ एक महत्वपूर्ण मदद है क्योंकि यह बराबर जावा कोड की तुलना में पार्स करने के लिए बहुत सरल है।


डाउनवॉटर कृपया मन को समझाएगा कि क्यों ?
सेमीस्टर

-5

टेक्स्ट सोर्स कोड एक संरचना है जो मानव द्वारा आसानी से पढ़ी और संशोधित की जा सकती है ।

बाइट कोड एक संरचना है जिसे मशीन द्वारा आसानी से पढ़ा और निष्पादित किया जा सकता है ।

चूँकि सभी JVM कोड के साथ पढ़ता है और उस पर अमल करता है, बाइट कोड JVM द्वारा खपत के लिए बेहतर है।

मैंने देखा कि अभी तक कोई उदाहरण नहीं आया है। मूर्खतापूर्ण छद्म उदाहरण:

//Source code
i += 1 + 5 * 2 + x;

// Byte code
i += 11, i += x
____

//Source code
i = sin(1);

// Byte code
i = 0.8414709848
_____

//Source code
i = sin(x)^2+cos(x)^2;

// Byte code (actually that one isn't true)
i = 1

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


2
उन बाइट कोड "उदाहरण" मानव पठनीय हैं। यह बाइट कोड बिल्कुल नहीं है। यह भ्रामक है और पूछे गए प्रश्न को भी संबोधित नहीं करता है।
वाइल्डकार्ड

@Wildcard आपने याद किया होगा कि यह एक मंच है, जिसे इंसानों द्वारा पढ़ा जाता है। इसलिए मैंने मानव पठनीय रूप में सामग्री डाली। यह देखते हुए कि फोरम सॉफ्टवेयर इंजीनियरिंग के बारे में है, पाठकों को सरल अमूर्त की अवधारणा को समझने के लिए कहने के लिए बहुत कुछ नहीं पूछ रहा है।
पीटर

मानव पठनीय रूप स्रोत कोड है, बाइट कोड नहीं। आप पूर्व-संगणित, नॉट बाइट कोड के साथ स्रोत कोड का चित्रण कर रहे हैं । और मुझे यह याद नहीं था कि यह एक मानव-पठनीय मंच है: आप वह हैं जिसने बाइट कोड के किसी भी उदाहरण को शामिल नहीं करने के लिए अन्य उत्तरदाताओं की आलोचना की, न कि मुझे। तो आप कहते हैं, "मुझे लगता है कि अभी तक कोई उदाहरण नहीं आया है," और फिर गैर- उदाहरण देने के लिए आगे बढ़ें जो बाइट कोड को बिल्कुल स्पष्ट नहीं करते हैं। और यह अभी भी सवाल को संबोधित नहीं करता है। सवाल फिर से।
वाइल्डकार्ड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.