2009-05-22 9 views
7

मैं गतिशील रूप से एक जावा। क्लास फ़ाइल लोड करने की कोशिश कर रहा हूं और प्रतिबिंब द्वारा इसे कॉल करता हूं।जावा क्लासलोडिंग बहुत धीमी गति से चल रही है?

मुझे फू नामक एक कक्षा मिली है; इसमें एक खाली कन्स्ट्रक्टर है और इसमें एक विधि है जिसे डिट() कहा जाता है जो स्ट्रिंग तर्क लेता है और स्ट्रिंग देता है। इसके अलावा यह स्ट्रिंग को उलट देता है।

URL url = new URL("file://C:/jtest/"); 
    URLClassLoader loader = new URLClassLoader(new URL[]{url}); 
    Class<?> cl = loader.loadClass("Foo"); 
    Constructor<?> cons = cl.getConstructor((Class[])null); 
    Object ins = cons.newInstance(new Object[]{}); 
    Method meth = cl.getDeclaredMethod("doit", String.class); 
    Object ret = meth.invoke(ins, new Object[]{"!dlroW olleH"}); 
    System.out.println((String)ret); 

जैसी उम्मीद थी इस प्रिंट:

यहाँ मेरी कोड है "नमस्ते दुनिया!"। हालांकि, इसे पूरा करने के लिए लगभग 30 सेकंड लगता है। मुझे पता है कि प्रतिबिंब धीमा है, लेकिन मुझे उम्मीद है कि यह 10 एमएस या कुछ हो।

मैं जेआरई 1.6.0_13 के साथ एक्लिप्स का उपयोग कर रहा हूं, और मैं विंडोज विस्टा चला रहा हूं।

मैं यहाँ क्या गलत कर रहा हूं?

धन्यवाद।

संपादित करें: मैंने कोड प्रोफाइल किया है, और इसका पूरा समय तीसरी पंक्ति (loadClass()) में उपयोग किया जाता है। बाकी सब कुछ तुरंत होता है।

संपादित करें: मैंने कोड को लूप में रखा है; धीमी गति किसी भी तरह अनुकूलित हो जाती है और केवल पहले लूप पर 30 सेकंड लेती है।

संपादित करें: मुझे समाधान मिला है।

बजाय:

URL url = new URL("file:/C:/jtest/");

अब यह पूरी तरह से काम करता है:

URL url = new URL("file://C:/jtest/");

मैं यह करने के लिए बदल दिया है। मुझे नहीं पता कि यह क्यों काम करता है, लेकिन मुझे नहीं लगता कि मैं (और 5 अन्य लोग) इसे कैसे चूक सकते थे। अब मुझे गूंगा लगता है ..

+1

लोड क्लास पहली बार कैश की जांच करता है यह देखने के लिए कि कक्षा पहले ही लोड हो चुकी है, अगर मुझे सही याद है। यह समझाएगा कि दूसरे पुनरावृत्ति पर लंबे समय तक क्यों नहीं लगता है। –

+0

क्या पैकेज में असली "फू" है? डिफ़ॉल्ट पैकेज से लोड हो रहा है (कोई पैकेज नहीं) अजीब प्रभाव हो सकता है। Foo.Foo पर जाने का प्रयास करें। – flicken

+0

यह दिलचस्प है ... नया यूआरएल ("फाइल:/सी:/जेटेस्ट /")। GetPath() है/सी:/jtest /। मुझे आश्चर्य है कि URLClassLoader इसका अर्थ कैसे करता है। –

उत्तर

5
30 सेकंड पर

, आप (? वर्ग की लोडिंग में? उदाहरण बनाने में? विधि को देख में आदि?) जहां समस्या है अपने कोड "प्रोफाइल" और वास्तव में देखने के लिए सक्षम होना चाहिए

चूंकि इसमें 30 सेकंड लगते हैं (और 10ms या उससे भी कम के क्रम में कुछ छोटा नहीं है), तो आप अपने कोड की प्रत्येक पंक्ति के बीच System.out.println(new Date()); का उपयोग कर सकते हैं।

मुझे संदेह है कि आपको यह लोडर मिल जाएगा।loadClass (स्ट्रिंग) इतनी देर ले रहा है - और मुझे संदेह है कि आप पाएंगे कि आपके पास या तो बहुत लंबा क्लासपाथ है, या एक क्लासपाथ जिसमें किसी प्रकार का नेटवर्क संसाधन शामिल है।

+2

@ अज्ञात: उस मामले में (और यदि आपने समस्या हल की है) तो आपको उस उत्तर को पोस्ट करना चाहिए जिसे आप जानते हैं और सही है। –

5

अपना डिफ़ॉल्ट क्लासपाथ देखें। शायद यह एक अनुपलब्ध नेटवर्क शेयर या ऐसा कुछ संदर्भित करता है।

+0

मैं यह कैसे कर सकता हूं? – Lucky

+0

echo% CLASSPATH% कमांड प्रॉम्प्ट –

+0

में या ग्रहण –

2

आपके कोड में कुछ भी गलत नहीं है ... मैं आपके प्रोग्राम को एक सेकंड से भी कम समय में संकलित करने में सक्षम था। मैं विस्टा बिजनेस पर जावा 1.6.11 चला रहा हूं।

शायद आपकी public string doit(string arg) विधि इतनी लंबी हो रही है। क्या आप प्रतिबिंब का उपयोग किए बिना इसे आविष्कार करने का प्रयास कर सकते हैं यह देखने के लिए कि क्या इसमें लंबा समय लगता है? doit() होने का प्रयास करने के लिए यह देखने के लिए कि आप अपने रिवर्सल एल्गोरिदम को धीमा कर रहे हैं या नहीं, यह देखने के लिए बस पैरामीटर को वापस ले जाएं (वर्णों को उलटने के बजाय)।

+0

में सेटिंग्स की जांच करें, उन्होंने कहा कि इसे पूरा होने में 30 सेकंड लग गए। मैं निष्पादन को पूरा करने के लिए निष्पादन को पूरा करने का मतलब मानता हूं। –

+0

यह संकलित और एक सेकंड से भी कम समय में भाग गया। यही कारण है कि मैंने उसे अपने काम() विधि के एक अलग कार्यान्वयन के साथ निष्पादित करने का प्रयास करने के लिए कहा। गैर-प्रतिबिंब कोड का उपयोग करते समय – Cuga

+0

doit() तुरंत लौटाता है। – Lucky

3

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

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

2

क्या यह संभव है:

ClassLoaderTest.class.getClassLoader() 

, जहां ClassLoaderTest वर्ग आप या, में चला रहे हैं, बशर्ते आप कर रहे हैं है। नहीं एक स्थिर संदर्भ में चल रहा है, तो:

this.getClass().getClassLoader()` 

इनमें से किसी एक नया वर्ग लोडर instantiating आप बचत होगी।

लेकिन मुझे नहीं पता कि इससे आपकी मदद भी होगी (आपको प्रोफाइल करना होगा), और प्रतिबिंब हमेशा धीमा होने वाला है। उसके चारों ओर नहीं हो रहा है। बेशक, इस और अन्य कारणों से इसे उत्पादन में कम से कम इस्तेमाल किया जाना चाहिए।

संपादित करें: चूंकि लोड क्लास ज्यादातर समय ले रहा है, यह हो सकता है कि सी: \ jtest अव्यवस्थित हो। आप निर्देशिका में Foo.class को अकेले डालने और URL के रूप में उपयोग करने का प्रयास कर सकते हैं। बेशक, दूसरी बार यह तेज़ कारण है कि फू पहले ही लोड हो चुका है।

6

आपकी जानकारी के लिए: शायद आपके लिए थोड़ा देर हो चुकी है, लेकिन मैं एक ही मुद्दे पर ठोकर खाई और यह पोस्ट पाया।

ऐसा लगता है कि // रिमोट सर्च को मजबूर कर रहा है, अगर आप -verbose के साथ भागते हैं: कक्षा में अज्ञातहोस्ट एक्सेप्शन लोड होता है इसलिए इसे कक्षा लोडिंग के दौरान आंतरिक रूप से फेंक दिया जाना चाहिए।

यूआरएल url = नया URL ("फ़ाइल: // स्थानीय होस्ट/सी:/jtest /")

मैं निम्नलिखित की कोशिश की,

और यह आपके एकल स्लैश समाधान के रूप में तेज़ी से (लगभग) काम करता है।

+0

मुझे 4 मिनट रनटाइम और बाल खींचने के घंटे बचाए – MonoThreaded

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