2010-11-04 18 views
5

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

हमारे पास कई एनोटेशन-संचालित पहलू वर्ग भी हैं जिन्हें हम वेब सेवा कक्षाओं पर लागू करते हैं। poincut अभिव्यक्ति शुरुआत में इस तरह देखा:

@Pointcut("execution(public * my.package.service.business.*BusinessServiceImpl.*(..))") 
    public void methodsToBeLogged() { 
    } 

और AOP विन्यास में प्रवेश के माध्यम से सेवाओं पर सक्षम किया गया था।

लेकिन जब वेब सर्विसेज की संख्या बढ़ी, तो हमने अपने सर्वर पर OutOfMemoryException एस का अनुभव करना शुरू कर दिया। कुछ प्रोफाइलिंग और विश्लेषण करने के बाद यह दिखाई दिया कि स्मृति को कैश द्वारा लिया जाता है जिसे AspectJExpressionPointcut क्लास के उदाहरणों द्वारा रखा जाता है।

प्रत्येक उदाहरण का कैश लगभग 5 एमबी था। और चूंकि हमारे पास 3 पहलुओं और 30 सेवाओं के परिणामस्वरूप कुल मिलाकर 450 एमबी डेटा रखने वाले 9 0 उदाहरण सामने आए।

कैश की सामग्री की जांच करने के बाद हमें एहसास हुआ कि इसमें WAR में मौजूद सभी वर्गों के लिए जावा प्रतिबिंब विधि उदाहरण हैं जो मेरे.package.service.business पैकेज का हिस्सा नहीं हैं।

@Pointcut("execution(public * my.package.service.business.*BusinessServiceImpl.*(..)) && 
within(my.package.service.business..*)") 
    public void methodsToBeLogged() { 
    } 

मेमोरी उपयोग फिर से सामान्य करने के लिए नीचे था: बिंदु कटौती अभिव्यक्ति modifing के बाद अतिरिक्त within खंड है। और सभी AspectJExpressionPointcut उदाहरणों को एक साथ 1 एमबी से कम ले लिया।

कोई बता सकता है कि वह क्यों है? और क्यों पहली बार कट अभिव्यक्ति पर्याप्त नहीं है? AspectJExpressionPointcut का कैश क्यों साझा नहीं किया गया है?

उत्तर

7

AspectJExpressionPointcut एक कैश (छाया मैच कैश) का उपयोग करता है जो कि एओपी को किसी निश्चित विधि कॉल पर लागू किया जाना चाहिए या नहीं, पॉइंटकट अभिव्यक्ति के आधार पर। यह कैश संभवतः बहुत सारी स्मृति का उपभोग करता है।

Additionaly

, अगर वहाँ AspectJExpressionPointcut.matches (कक्षा targetClass को फोन करके एक pointcut अभिव्यक्ति मैच है या नहीं, स्प्रिंग पहले जांच करता है कि एक सेम वर्ग, संभवतः या नहीं मेल खा सकते हैं, को देखने के लिए एक विशिष्ट सेम के सभी तरीकों की पेशकश से पहले)। यह विधि AspectJ के PointcutExpressionImpl.couldPossiblyMatch() विधि को प्रस्तुत करती है। यह तेज करेगा, यह जांच लें कि कोई वर्ग 'संभवतः' पॉइंटकट अभिव्यक्ति से मेल खा सकता है या कभी भी 'निश्चित रूप से' मिलान नहीं करेगा। आइडेंटजे डेवलपर्स के मुताबिक एक पॉइंटकट का उपयोग करके, अधिक निश्चित संख्या में परिणाम मिलता है। वे recommend to never use a standalone kind of pointcuts (execution, call, get, set), but combine these with within भी।

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

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

AspectJExpressionPointcut क्लास के अंदर एक और संभावित मेमोरी होग पॉइंटकूटर्स है। यह पार्सर संभवतः एप्लिकेशन कॉन्टेक्स्ट में सभी AspectJExpressionPointcuts में साझा किया जा सकता है। जेआईआरए टिकट SPR-7678 पर लूट लें।

+0

उत्कृष्ट उत्तर! –

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

  • कोई संबंधित समस्या नहीं^_^