2009-12-01 10 views
9

मुझे समझ है कि मेटा डेटा स्टोर करने के लिए परम आकार का उपयोग किया जाता है, जिसमें बाइट कोड, स्थिर सामान इत्यादि शामिल होंगे।प्रतिबिंब पर्म आकार को कैसे प्रभावित करता है?

मेरा प्रश्न प्रतिबिंब का उपयोग परम आकार को कैसे प्रभावित करता है, अगर यह कभी करता है। मेरा मतलब है अगर कार्यक्रम-ए, चल वस्तुओं के सामान्य तरीके से और कार्यक्रम बी सब कुछ खत्म हो प्रतिबिंब का उपयोग करता है का उपयोग करता है कैसे दो कार्यक्रमों में से पर्म-आकार की तुलना करेंगे?

उत्तर

7

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

उदाहरण के लिए getDeclaredMethod(String name, Class<?>... parameterTypes) विधि पैरामीटर को आंतरिककृत किया जाएगा।

यह टुकड़ा होगा अच्छी तरह से पर्म अंतरिक्ष भरता:

Random random = new Random(); 
while(true){ 
    try { 
     X.class.getDeclaredMethod(toBinaryString(random.nextLong())); 
    } catch (Exception e) { 
    } 
} 

alt text http://img4.imageshack.us/img4/9725/permgen.jpg

यह कोई अंतर नहीं पड़ेगा कोई वास्तविक दुनिया आवेदन में।

+0

मुझे विश्वास है कि आप देख रहे हैं कि वहां नाम की खोज की जा रही है ताकि पहले से ही प्रशिक्षित विधि नामों पर '==' का उपयोग किया जा सके। (विश्वास नहीं है कि यह एक अच्छा विचार है।) चेहरे में, प्रतिबिंब कक्षाएं (कभी-कभी) बना सकता है। –

+0

(वे इंटर्न वाले स्ट्रिंग्स कचरा संग्रहण चक्र पर पूर्ण के साथ जीसीबल हैं, कार्यान्वयन की अच्छी गुणवत्ता मानते हैं।) –

+0

@ टॉम, क्या आप एक उदाहरण दे सकते हैं जहां प्रतिबिंब के कारण कक्षा बनाई जाती है? मैं दर्द होने की कोशिश नहीं कर रहा हूं, मैं वास्तव में इन मामलों के बारे में जानना चाहता हूं क्योंकि मैंने कभी नहीं देखा है। – PSpeed

3

मुझे पूरा यकीन नहीं है कि मैं सवाल समझता हूं लेकिन जावा कक्षाओं में पहले से ही उन सभी पर प्रतिबिंब करने की आवश्यकता है। ए। क्लास फ़ाइल इस बात के आधार पर नहीं बदली जाती है कि इसका उपयोग कैसे किया जाता है।

संपादित करें 1: "प्रतिबिंब" के प्रकार को बेहतर तरीके से अलग करने के लिए कुछ और विशिष्ट उदाहरण प्रदान करना, जिसके बारे में हम बात कर रहे हैं।

उदाहरण:

class Foo { 
    public void bar() { 
     System.out.println("Hello, world."); 
    } 
} 

// Conventional calling 
Foo f = new Foo(); 
foo.bar(); 

// Reflection based callling 
Class fooClass = Class.forName("Foo"); 
Method m = fooClass.getMethod("bar", null); 
Object f = fooClass.newInstance(); 
m.invoke(m, null);  

पारंपरिक बुला मामले में, Foo.class और इसके प्रत्यक्ष वर्ग निर्भरता के किसी भी लोड किया जाएगा। बार निष्पादित किया जाएगा। स्ट्रिंग्स "फू" और "बार" को कॉलिंग क्लास के हिस्से के रूप में पहले से ही इंटर्न किया जाएगा क्योंकि बाइट कोड रनटाइम पर कक्षाओं और विधियों को हल करने के लिए तारों का उपयोग करता है। (वास्तव में "बार" पूर्ण विधि हस्ताक्षर होगा, वास्तव में केवल "बार" से अधिक लंबा)

प्रतिबिंब मामले में, बिल्कुल वही होता है। लोड किया गया एकमात्र अतिरिक्त वर्ग Method.class है। यह अनुमति आकार के लिए एकमात्र प्रभाव होना चाहिए।

बाद के मामले में प्रदर्शन प्रभाव पड़ता है। विधि लुक-अप अपेक्षाकृत महंगी है इसलिए जब आप कर सकते हैं विधि ऑब्जेक्ट कैश करने की सलाह दी जाती है। आमंत्रित करने के लिए अतिरिक्त विधि कॉल में थोड़ा प्रदर्शन प्रभाव पड़ता है क्योंकि यह एक अतिरिक्त विधि कॉल है। हॉटस्पॉट को इस कॉल के माध्यम से अनुकूलित करने में परेशानी होगी ... कम से कम सामान्य से अधिक। JITING बिल्कुल वही होता है।

संपादित करें 2: कुछ अतिरिक्त वस्तुओं है कि प्रतिबिंब के दौरान लोड किए गए हैं ... यह उल्लेख करते हुए

java.lang.Class बना सकते हैं और कैश विधि वस्तुओं (या फील्ड वस्तुओं, आदि) का उपयोग करने पर होगा। इन्हें सॉफ़्ट रेफरेंस में कैश किया जाता है और यदि स्मृति उपयोग की आवश्यकता होती है तो उसे फिर से दावा किया जाएगा।

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

+0

कक्षाएं तेजी से पहुंच के लिए प्रतिबिंब कार्यान्वयन द्वारा गतिशील रूप से उत्पन्न की जा सकती हैं। –

+0

संदर्भ कृपया? मैं हर समय प्रतिबिंब का उपयोग करता हूं (वास्तव में ... हर समय) और परिणामस्वरूप उत्पन्न एक भी वर्ग कभी नहीं देखा है। तीसरे पक्ष के पुस्तकालय कुछ सामान कर सकते हैं और गतिशील प्रॉक्सी सामान निश्चित रूप से रनटाइम कक्षा उत्पन्न करेगा। लेकिन कक्षा/वस्तु पर बस कॉलिंग विधियों को नहीं करना चाहिए। – PSpeed

+0

@ PSpeed..pls निम्न लिंक की जांच करें https://jaxb.dev.java.net/issues/show_bug.cgi?id=581 –

2

पहला उत्तर मूल रूप से सही है - चाहे कक्षा सामान्य रूप से लोड हो या प्रतिबिंब के माध्यम से कोई फर्क नहीं पड़ता। किसी भी तरह से यह लोड हो गया है। मैं आंतरिक स्ट्रिंग्स में किसी भी अंतर के बारे में नहीं सोच सकता जो मुझे पता है।

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

प्रतिबिंब के साथ, केवल 1 वर्ग लोड किया जाएगा। बिना, इस कोड के साथ कक्षा लोड होने पर, सभी 100 आयातित वर्ग लोड होंगे क्योंकि सभी संदर्भित हैं। इसलिए, अधिक कक्षाएं पार स्थान में लोड हो जाती हैं।

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

3

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

हमेशा की तरह, सलाह है: यथार्थवादी परिस्थितियों में अपना कोड प्रोफाइल करें।

+0

क्या आपका मतलब "मूल कोड" ऊपर है? कक्षाएं पहले से ही बाइट कोड हैं। हॉटस्पॉट को प्रतिबिंब की कॉल के माध्यम से अनुकूलित करने में परेशानी होगी लेकिन जेआईटी वही व्यवहार करता है। – PSpeed

+0

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

+0

+1: बस जीसी लॉग को सक्रिय करें और System.out - [अनलोडिंग क्लास sun.reflect.GeneratedMethodAccessor1403] [क्लास को अनलोडिंग करें sun.reflect.GeneratedConstructorAccessor446] [क्लास को अनलोड करना sun.reflect.GeneratedMethodAccessor562] - ये प्रतिबिंब द्वारा उत्पन्न होते हैं कार्यान्वयन। – fglez

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

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