Java AOT कंपाइलर कैसे काम करते हैं?


18

वहाँ कुछ उपकरण हैं ( एक्सेलसियर जेईटी , आदि) जो जावा ऐप को मूल निष्पादन योग्य ( *.exe) में बदलने का दावा करते हैं । हालांकि यह मेरी समझ है कि ये उपकरण वास्तव में केवल देशी आवरण बना रहे हैं javaजो शेल या कमांड-लाइन से आह्वान / निष्पादित करते हैं ।

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

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

इसलिए मैं पूछता हूं: ये उपकरण वास्तव में जावा क्लास की फाइलों को मूल निष्पादन योग्य कैसे बनाते हैं, या वे करते हैं?

जवाबों:


26

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

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

यह केवल कार्यान्वयन नहीं है। यह कहते हुए कि आप जावा के लिए एक मानक lib-esque रनटाइम नहीं बना सकते हैं और देशी मशीन कोड को संकलित कर सकते हैं और रनटाइम के भीतर नए ऑब्जेक्ट के कॉल को मशीन में हैंडल करते हैं और मशीन पर सिस्टम कॉल में फ़ाइल एक्सेस करते हैं। और यही समय (AIT JIT के बजाय AOT) संकलक का काम करता है। जो रनटाइम क्या आप ... आप इसे एक JVM कार्यान्वयन कह सकते हैं होगा कॉल (और यह है JVM विनिर्देश का पालन करें) या एक क्रम पर्यावरण या जावा के लिए मानक lib। वहाँ और यह अनिवार्य रूप से एक ही बात करता है।

यह javacदेशी मशीन को लक्षित करने के लिए फिर से लागू करके किया जा सकता है (जो कि जीसीजे ने ऐसा ही किया है)। या यह javacकिसी अन्य मशीन के लिए मशीन (या बाइट) कोड में उत्पन्न बाइट कोड का अनुवाद करने के साथ किया जा सकता है - यही एंड्रॉइड करता है। विकिपीडिया के आधार पर कि एक्सेलसियर JET भी क्या करता है ("कंपाइलर पोर्टेबल जावा बाइट कोड को वांछित हार्डवेयर और ऑपरेटिंग सिस्टम (OS)" के लिए अनुकूलित निष्पादनों में बदल देता है), और वही रोबोवीएम के लिए सही है

जावा के साथ अतिरिक्त जटिलताएं हैं इसका मतलब है कि यह एक विशेष दृष्टिकोण के रूप में करना बहुत कठिन है। कक्षाओं के गतिशील लोडिंग ( class.forName()) या समीपवर्ती ऑब्जेक्ट्स को डायनामिक्स की आवश्यकता होती है जो एओटी कंपाइलर आसानी से प्रदान नहीं करते हैं और इसलिए उनके संबंधित जेवीएम में उन कक्षाओं को संभालने के लिए एक जेआईटी कंपाइलर (एक्सेलसियर जेईटी) या एक दुभाषिया (जीसीजे) भी शामिल होना चाहिए जो पहले से तय नहीं किए जा सकते। देशी।

याद रखें, जेवीएम एक विनिर्देश है , जिसमें कई कार्यान्वयन हैं । सी मानक पुस्तकालय कई अलग-अलग कार्यान्वयनों के साथ एक विनिर्देश भी है

Java8 के साथ, AOT संकलन पर एक उचित काम किया गया है। सबसे अच्छा, कोई केवल टेक्स्ट बॉक्स की सीमा के भीतर सामान्य रूप से एओटी का सारांश दे सकता है। हालांकि, 2015 (2015 के अगस्त) के लिए जेवीएम भाषा शिखर सम्मेलन में, एक प्रस्तुति थी: जावा गोस एओटी (यूट्यूब वीडियो)। यह वीडियो 40 मिनट लंबा है और कई गहरे तकनीकी पहलुओं और प्रदर्शन बेंचमार्क में जाता है।


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

@ paulpaul1076 मैं उस वीडियो को देखने का सुझाव दूंगा जिसे मैंने लिंक किया था। मैं इसमें काफी कुछ कर सकता हूं क्योंकि मैं उचित रूप से एक टिप्पणी में फिट हो सकता हूं।

4

gcj न्यूनतम चल उदाहरण

आप एक खुले स्रोत कार्यान्वयन का निरीक्षण भी कर सकते हैं जैसे gcj(अब अप्रचलित)। जैसे जावा फ़ाइल:

public class Main {
    public static void main(String args[]) {
        System.out.println("hello world");
    }
}

फिर संकलित करें और चलाएं:

gcj -c Main.java
gcj --main=Main -o Main Main.o
./Main

अब आप इसे विघटित करने के लिए स्वतंत्र हैं और देखें कि यह कैसे काम करता है।

file Main.o यह एक योगिनी फ़ाइल है।

readelf -d Main | grep NEEDED कहते हैं कि यह गतिशील पुस्तकालयों पर निर्भर करता है:

0x0000000000000001 (NEEDED)             Shared library: [libgcj.so.14]
0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]

तो libgcj.so वह जगह होनी चाहिए जहां जावा कार्यक्षमता कार्यान्वित की जाती है।

आप तब इसे अपघटित कर सकते हैं:

objdump -Cdr Main.o

और देखें कि यह कैसे लागू किया जाता है।

C ++ की तरह दिखता है, बहुत सारे नाम mangling और अप्रत्यक्ष पॉलीमॉर्फिक फ़ंक्शन कॉल।

मुझे आश्चर्य है कि कचरा संग्रह किस तरह से होता है। यह देखने लायक होगा: /programming/7100776/garbage-collection-implementation-in-compiled-languages और GC जैसी अन्य संकलित भाषाओं में।

उबंटू 14.04, जीसीसी 4.8.4 पर परीक्षण किया गया।

इसके अलावा https://en.wikipedia.org/wiki/Android_Runtime , एंड्रॉइड 5 की रीढ़ की हड्डी पर एक नज़र डालें , जो एंड्रॉइड ऐप को अनुकूलित करने के लिए पूर्ण एओटी करता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.