2016-11-08 11 views
7

का कहना है कि मेरे पास एक ही कक्षा के 2 उदाहरण हैं, लेकिन वे निर्माण समय पर निर्धारित अंतिम बूलियन क्षेत्र के आधार पर अलग-अलग व्यवहार करते हैं (विभिन्न कोड पथों का पालन करें)। तो कुछ की तरह: flag के लिए विभिन्न मूल्यों के साथ Foo कीमॉडर्म JVMs एक ही कक्षा के अलग-अलग उदाहरणों को अलग-अलग अनुकूलित कर सकता है?

public class Foo { 
    private final boolean flag; 

    public Foo(boolean flagValue) { 
     this.flag = flagValue; 
    } 

    public void f() { 
     if (flag) { 
     doSomething(); 
     } else { 
     doSomethingElse(); 
     } 
    } 
} 

2 उदाहरणों सिद्धांत रूप में, 2 अलग विधानसभाओं द्वारा समर्थित किया जा सकता है जिससे अगर (काल्पनिक उदाहरण के लिए खेद है, इसके सरलतम एक मैं कर सकता की लागत को नष्ट करने साथ आएं)।

तो मेरा सवाल है - क्या कोई भी जेवीएम वास्तव में ऐसा करता है? या एक एकल वर्ग हमेशा एक असेंबली द्वारा समर्थित है?

+1

जो आप वर्णन कर रहे हैं वह सबक्लासिंग की तरह बहुत भयानक लगता है, क्या आप स्पष्ट कर सकते हैं कि यह क्यों काम नहीं करेगा? मैं समस्या की सीमाओं को समझने की कोशिश कर रहा हूं चुनौतीपूर्ण नहीं हूं। – Taylor

+0

सभी उदाहरण एक ही कोड साझा करते हैं। आपका प्रश्न समझ में नहीं आता है। – EJP

+2

@ टेलर मुझे क्षमा करें यदि मैं ओपी की व्याख्या करने की हिम्मत करता हूं, लेकिन मुझे लगता है कि वह जो भी पूछ रहा है वह उचित पैटर्न नहीं है (जो स्पष्ट रूप से विरासत होगा), लेकिन यदि JVMs "बुद्धिमान" हैं जो उपयोग को हटाने के लिए पर्याप्त हैं 'फ्लैग' वैरिएबल और पूरे वर्ग के लिए दो अलग-अलग बाइटकोड उत्पन्न करें (एक' सत्य 'शाखाओं के अनुरूप, और दूसरा' झूठी 'के लिए)। –

उत्तर

7

हां, जेवीएम अनुकूलन के इस रूप को करते हैं। आपके मामले में, यह हमेशा सत्य होने के लिए inlining and adaptive optimization का परिणाम होगा। निम्नलिखित कोड पर विचार करें:

Foo foo = new Foo(true); 
foo.f(); 

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

Foo foo = new Foo(true); 
foo.doSomething(); 

की कॉल साइट के monomorphism पर निर्भर करते हैं इसलिए करता है:

Foo foo = new Foo(true); 
if (foo.flag) { 
    doSomething(); 
} else { 
    doSomethingElse(); 
} 

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

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

+2

इस विशिष्ट मामले में, JVM डेटा को प्रोफाइल किए बिना स्थिर विश्लेषण द्वारा परिणाम भी उत्पन्न कर सकता है। यह कन्स्ट्रक्टर के कोड को रेखांकित करने का नतीजा दिखाकर और अधिक सहज हो जाएगा, क्योंकि मूल रूप से परिणाम 'foo.flag = true है; अगर (foo.flag) ... 'जिसे अनुकूलित करने के लिए' ध्वज 'को' अंतिम 'होने की भी आवश्यकता नहीं है। फॉलो-अप कोड के आधार पर, यह इस विशिष्ट कोड पथ के लिए 'Foo' उदाहरण भी नहीं बनाएगा। – Holger

5

निम्नलिखित हॉटस्पॉट पर लागू होता है, अन्य JVMs विभिन्न अनुकूलन लागू कर सकते हैं।

ऐसे मामलों static final क्षेत्रों के लिए सौंपा चालू कर रहे हैं और फिर अन्य कोड से जाना जाता है और वी एम -XX:+TrustFinalNonStaticFields के साथ शुरू किया गया है तो ऐसे मामलों निरंतर तह में भाग ले सकते हैं और इनलाइन करने CONSTANT.f() बाहर होने से विभिन्न शाखाओं में परिणाम कर सकते हैं।

विशेषाधिकार प्राप्त कोड के लिए उपलब्ध एक और दृष्टिकोण sun.misc.Unsafe.defineAnonymousClass(Class<?>, byte[], Object[]) के माध्यम से उदाहरणों के बजाय अज्ञात कक्षाएं बना रहा है और प्रत्येक वर्ग के लिए कक्षा निरंतर पैचिंग कर रहा है, लेकिन आखिरकार इसे क्लाइंट निरंतर के माध्यम से संदर्भित किया जाना चाहिए ताकि अनुकूलन पर कोई प्रभाव हो सके।

संबंधित मुद्दे