2012-02-09 13 views
12

हमारी परियोजना कुछ जावा बाइटकोड वाद्ययंत्र करता है। और हम कुछ अजीब व्यवहार पर ठोकर खाई।ओरेकल और ग्रहण के कंपाइलर्स द्वारा उत्पादित जावा बाइटकोड में अंतर

public void a() { 
    new Integer(2); 
    } 

Oracle की javac निम्नलिखित बाईटकोड में ऊपर संकलित:

0: new #2; //class java/lang/Integer 
    3: dup 
    4: iconst_2 
    5: invokespecial #3; //Method java/lang/Integer."<init>":(I)V 
    8: pop 
    9: return 

और में ग्रहण का संकलक: निम्नलिखित कोड का टुकड़ा मान लीजिए

0: new #15; //class java/lang/Integer 
    3: iconst_2 
    4: invokespecial #17; //Method java/lang/Integer."<init>":(I)V 
    7: return 

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

मेरे प्रश्न हैं:

  1. वहाँ विभिन्न compilers के बीच मतभेद के कुछ सिंहावलोकन है? एक लेख/ब्लॉग पोस्ट?
  2. क्या मैं सुरक्षित रूप से निष्कर्ष निकाल सकता हूं कि यदि "नया" और "invokespecial" के बीच कोई "डुप्लिक" नहीं है तो ऑब्जेक्ट प्रारंभ करने के बाद उपयोग नहीं किया जाता है?
+4

बाइटकोड के उपकरण के साथ आपका लक्ष्य क्या है? क्या यह अंतर आपके लिए एक समस्या का कारण बनता है? ध्यान दें कि बाइटकोड वास्तव में जावा कंपाइलर का उत्पादन करने के बारे में कोई गारंटी नहीं है।यह पूरी तरह से संभव है कि भविष्य के संस्करण में ओरेकल के 'जावैक' अब आप जो देखते हैं उससे अलग कुछ उत्पादन करेंगे - इसलिए एक ऐसा प्रोग्राम लिखना अच्छा नहीं है जो संकलक द्वारा उत्पादित सटीक बाइटकोड पर निर्भर करता है। – Jesper

+0

क्या आप ग्रहण के लिए विभिन्न जेडीके का उपयोग करते हैं? – Nishant

उत्तर

3
  1. मैं सुरक्षित रूप से निष्कर्ष निकाल सकते हैं, अगर वहाँ कोई बीच 'नई' और 'invokespecial "तो वस्तु आरंभीकरण के बाद नहीं किया जाता है" dup "है?

मुझे यकीन है कि तुम क्या मतलब है बिल्कुल नहीं कर रहा हूँ, लेकिन निर्मित ऑब्जेक्ट के लिए एक संदर्भ निर्माता द्वारा कहीं संग्रहीत किया जा सकता है। इसलिए कॉलिंग विधि प्रारंभिकरण के बाद ऑब्जेक्ट का उपयोग नहीं कर सकती है लेकिन ऑब्जेक्ट अभी भी पहुंच योग्य हो सकता है और इसलिए कचरा कचरा नहीं हो सकता है।

6

यदि बहुत dupनई invokespecial तो वस्तु के बीच और आमतौर पर संकलन के बाद किया जाता है। उदाहरण के लिए, क्षेत्र आरंभीकरण आमतौर पर नई का एक अनुक्रम, dup, invokespecial & putfield है। हालांकि, आपके उदाहरण में अंतिम निर्देश पॉप है जो ऑब्जेक्ट को स्टैक से साफ़ करता है - इस प्रकार आप यह मान सकते हैं कि इस ऑब्जेक्ट का उपयोग नहीं किया जाता है।

+0

जैसा कि एएच द्वारा इंगित किया गया है, पॉप का मतलब केवल यह है कि कॉलर द्वारा इसका उपयोग नहीं किया जाता है। ऑब्जेक्ट स्वयं ही सीटीआर में संदर्भों को दूर कर सकता है। – Antimony

1

पासिंग इस संदर्भ इस पैटर्न एक सा

public class Bump { 

    Test t; 

    public Bump() { 
     new Test(this); 
    } 
    public void setT(Test t) { 
     this.t = t; 
    } 
    } 

टूट जाएगा और फिर एक इस इस्तेमाल कर सकते हैं वापस :)

public class Test { 

    Bump b; 

    public Test(Bump b) { 
     this.b = b; 
     b.setT(this); 
    } 
    } 

परिणाम के भंडारण के लिए मज़े :)