मैं एक तृतीय पक्ष लाइब्रेरी का उपयोग कर रहा हूं जो गतिशील रूप से जावा कक्षाओं के उदाहरण बनाता है और Introspector.getBeanInfo
की सहायता से उन उदाहरणों को पॉप्युलेट करता है। कुछ अनुरोधों के परिणामस्वरूप 5 या 6 लगातार कॉल Introspector.getBeanInfo
पर हो सकती हैं। मैंने पाया है कि जब एप्लिकेशन लगभग एक घंटे तक निष्क्रिय होता है या तो Introspector.getBeanInfo
पर पहली कॉल को बाद में कॉल (< 100 मिलीसेकंड) बनाम (20-60 सेकेंड) निष्पादित करने में काफी लंबा समय लगता है। अगले कुछ मिनटों में किए गए कॉल < 100 मिलीसेकंड लेते रहेंगे, लेकिन जब मैं एक और घंटे इंतजार करता हूं तो पहले कॉल में 20-60 सेकंड लगते हैं।निष्क्रियता के बाद java.beans.Introspector.getBeanInfo को कॉल करते समय प्रदर्शन समस्याएं
एक साधारण परीक्षण अनुप्रयोग के साथ व्यवहार को फिर से बनाने के प्रयास में मुझे एक समान व्यवहार मिला है जब एक जावा एप्लिकेशन स्वयं एक घंटे तक नहीं चलाया जाता है। उदाहरण के लिए, यदि मैं निम्नलिखित कंसोल ऐप चलाता हूं तो इसे पूरा करने में 15 मिलीसेकंड लग सकते हैं। यदि मैं एक घंटे प्रतीक्षा करता हूं और एप्लिकेशन को फिर से चलाता हूं तो इसे पूरा होने में 20 सेकंड लगते हैं।
long start = System.currentTimeMillis();
System.out.println("Start");
Introspector.getBeanInfo(MyClass.class, Object.class);
long end = System.currentTimeMillis();
System.out.println("End: " + (end-start));
मैं मूल रूप से सोचा था कि तथ्य यह है कि इस मुद्दे को Introspector वर्ग प्रयास मानक नामकरण सम्मेलनों के आधार पर कक्षाओं के उदाहरण है कि अपने आवेदन में मौजूद नहीं है (उदाहरण के लिए, MyClassBeanInfo
) बनाने के लिए से संबंधित हो सकता है, और यह था उन वर्गों को खोजने के प्रयास में जार फ़ाइलों को स्कैन करने में काफी समय लग रहा है (मेरे जावा एप्लिकेशन में 100 से अधिक संदर्भित जार फाइलें हैं), लेकिन मैंने प्रतिबिंब का उपयोग करके Introspector.getBeanInfo(MyClass.class, Object.class, Introspector.IGNORE_ALL_BEANINFO)
कहा (यह सूर्य के जेआरई में एक निजी विधि है जो देखकर कोड बीनइन्फो कक्षाओं के लुकअप को छोड़ने लगता है), और मैं अभी भी देरी को पुन: उत्पन्न करने में सक्षम था।
मैंने किसी भी प्रकार के जेआरई/जेवीएम जार कैश के बारे में जानकारी की खोज की है, लेकिन अभी तक इस व्यवहार को समझाने के लिए कुछ भी नहीं मिला है। किसी के पास कोई सुराग है कि यह किस तरह से व्यवहार करता है, और यदि कुछ भी है तो मैं इसे ठीक करने के लिए कर सकता हूं?
एक साइड नोट के रूप में मैं विंडोज एक्सपी पर जेडीके 1.6.0_21 का उपयोग कर रहा हूं। मैं उपयोग कर रहा हूँ तीसरी पार्टी लाइब्रेरी BlazeDS है। मेरा आवेदन स्प्रिंग/ब्लेज़डीएस एकीकरण का उपयोग कर टोमकैट में होस्ट किया गया है। flex.messaging.io.BeanProxy
की विधि में Introspector.getBeanInfo
पर कॉल करने के लिए (जहां Introspector.getBeanInfo
पर कॉल किया गया है) को इंगित करने के लिए मैं कई ब्लजडेड कक्षाओं को ओवरराइट करता हूं। इसके अलावा, BlazeDS BeanInfo को कैश करता है, इसलिए Introspector.getBeanInfo
पर कॉल केवल तब किया जाता है जब ब्लेज़ किसी ऑब्जेक्ट को deserializing कर रहा है जिसे जावा क्लास में मैप किया गया है जिसे अभी तक संसाधित नहीं किया गया है। इसलिए, मेरे पास इस मुद्दे के आसपास काम करने के अन्य तरीके हैं, लेकिन मैं वास्तव में जानना चाहूंगा कि इस व्यवहार के लिए वैध स्पष्टीकरण है या नहीं।
संपादित करें: मैंने समस्या को पुन: उत्पन्न करते समय कई बार प्रक्रिया पर jstack चलाया (धन्यवाद @ टॉम) और पुष्टि की कि यह जार फ़ाइलों को लोड करने से संबंधित है। मैं एक 20 सेकंड समय सीमा (देरी के कुल समय) पर धागे 5 बार फेंक दिया और हर बार निम्न परिणाम का उत्पादन किया:
"http-8080-exec-6" daemon prio=6 tid=0x65cae800 nid=0x1a50 runnable [0x67a3d000]
java.lang.Thread.State: RUNNABLE
at java.util.zip.ZipFile.open(Native Method)
at java.util.zip.ZipFile.<init>(Unknown Source)
at java.util.jar.JarFile.<init>(Unknown Source)
at java.util.jar.JarFile.<init>(Unknown Source)
at org.apache.catalina.loader.WebappClassLoader.openJARs(WebappClassLoader.java:2704)
at org.apache.catalina.loader.WebappClassLoader.findResourceInternal(WebappClassLoader.java:2945)
- locked <0x1804cc18> (a [Ljava.util.jar.JarFile;)
at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:2739)
at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:1144)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1639)
- locked <0x1803dd38> (a org.apache.catalina.loader.WebappClassLoader)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1517)
at java.beans.Introspector.instantiate(Unknown Source)
at java.beans.Introspector.findExplicitBeanInfo(Unknown Source)
- locked <0x434649a0> (a java.lang.Class for java.beans.Introspector)
at java.beans.Introspector.<init>(Unknown Source)
at java.beans.Introspector.getBeanInfo(Unknown Source)
- locked <0x181bed70> (a java.lang.Object)
मैं मदद नहीं कर सकता लेकिन लगता है कि JRE/JVM जार के कुछ प्रकार है कैश जो एक घंटे के बाद समाप्त हो रहा है और जार फ़ाइलों को फिर से स्कैन करने के लिए मजबूर कर रहा है, लेकिन मुझे ऐसे व्यवहार को रेखांकित करने वाले ऑनलाइन कुछ भी नहीं मिल रहे हैं।
संपादित करें: जैसा कि यह पता चला है कि टॉमकैट WebappClassLoader
कैश जेएआर फाइल करता है और समय-समय पर कैश को शुद्ध करता है। अब यह पता लगाने के लिए कि क्या कैश किसी भी तरह कॉन्फ़िगर करने योग्य है ...
संपादित करें: टोमकैट पिछली बार एक जार फ़ाइल तक पहुंचने के 90 सेकंड बाद सभी जेएआर फाइलों को बंद कर देता है। जार फ़ाइलों को बंद होने पर प्रिंट करने के लिए मैं WebappClassLoader
को ओवरराइट करता हूं। जार फ़ाइलों को बंद करने के बाद मैंने देरी को पुन: उत्पन्न करने की कोशिश की, लेकिन इसमें असमर्थ था।तो, यह मुझे बताता है कि या तो एक जेआरई/जेवीएम जार फ़ाइल कैश है, या ऑपरेटिंग सिस्टम (या मेरी मशीन, एंटीवायरस, आदि) में कुछ अंतर्निहित है जो लंबे विलंब के बाद धीमी लोड के समय का कारण बन रहा है। अभी भी इस पर काम कर रहे हैं ...
आप 'jstack' का उपयोग करने की कोशिश कर सकते हैं या यह देखने के लिए कि प्रोग्राम कहां मिल गया है। इसके अलावा, कोई नेटवर्क कनेक्शन शामिल है? –
yourkit प्रोफाइलर आपका दिन बचा सकता है .. सूरज जावा कोड में दिखना ठीक है और आप दिलचस्प चीजें सीख सकते हैं लेकिन यह बहुत अधिक समय लेता है। –
धन्यवाद @ टॉम - jstack –