2014-10-03 2 views
5

मैं एक Oracle 11g डेटाबेस से कनेक्ट करने के लिए एक डेटा स्रोत का उपयोग करता है बिलाव 7.0.54 के लिए तैनात एक वेब एप्लिकेशन है विफल रहा है। डेटास्रोत META-INF/context.xml में कॉन्फ़िगर किया गया है और मैंने ojdbc7.jar को <tomcat-install-dir>/lib में रखा है। मैं एक जेएनटीआई लुकअप का उपयोग करता हूं जिसे मैं एक सिंगलटन में संग्रहीत डेटासोर्स को पुनर्प्राप्त करने के लिए करता हूं ताकि प्रत्येक डीएओ कक्षा इसका उपयोग कर सके।मेमोरी रिसाव - oracle.jdbc.driver धागा बंद करने के लिए

सब कुछ उम्मीद के रूप में काम करता है, लेकिन जब मैं आवेदन undeploy (बिलाव प्रबंधक एप्लिकेशन के माध्यम से) मैं लॉग में देखें:

Oct 03, 2014 3:06:55 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads 
SEVERE: The web application [/myapp] appears to have started a thread named [oracle.jdbc.driver.BlockSource.ThreadedCachingBlockSource.BlockReleaser] but has failed to stop it. This is very likely to create a memory leak. 
Oct 03, 2014 3:06:57 PM org.apache.catalina.startup.HostConfig undeploy 
INFO: Undeploying context [/myapp] 

जब मैं डिबग मैं देख सकता हूँ इस सूत्र के रूप में जल्द डेटाबेस है के रूप में बनाया जाता है एक्सेस किया गया (डेटासोर्स के माध्यम से)।

मेरे डेटा स्रोत config:

<Context antiResourceLocking="false"> 
    <Resource name="jdbc/myapp" auth="Container" 
     type="javax.sql.DataSource" driverClassName="oracle.jdbc.OracleDriver" 
     maxActive="20" maxIdle="10" maxWait="-1" 
     username="myuser" password="mypass" 
     url="jdbc:oracle:thin:@myserver:1521:mysid" 
     removeAbandoned="true" removeAbandonedTimeout="10" logAbandoned="true" 
     validationQuery="SELECT 1 FROM DUAL" 
     testOnBorrow="true" testOnReturn="true" testWhileIdle="true" 
     timeBetweenEvictionRunsMillis="1800000" numTestsPerEvictionRun="3" 
     minEvictableIdleTimeMillis="1800000" 
    /> 
</Context> 

संपादित

आगे की जांच से पता चला है कि समस्या इसलिए होती डेटा स्रोत के दौरान आवेदन (या सर्वलेट) initialisation एक्सेस किया जाता है कि क्या है या नहीं किया है।

वास्तविक तथ्य में, समस्याग्रस्त धागा केवल बनाया गया है, और इस प्रकार ओरेकल के जेडीबीसी ड्राइवरों (या तो ojdbc6.jar या ojdbc7.jar) के 12 सी संस्करणों का उपयोग करते समय समस्या केवल मौजूद है।

अगर मैं की ojdbc6.jar धागा कभी नहीं बनाई गई है 11.2.0.4 संस्करण और स्मृति रिसाव चेतावनी कभी नहीं दिखाई देता है इस्तेमाल करने लगी।

मैं डाउनग्रेड करना होगा JDBC ड्राइवर (के रूप में https://stackoverflow.com/a/9177263/4105953 में सुझाव दिया)?

+0

सुनिश्चित करें कि आपका ऑरैक ड्राइवर 'वेब-आईएनएफ/lib' निर्देशिका में भी नहीं है। जैसे ही ऑटो रजिस्टर होगा और ओरेकल जेडीबीसी सामानों में से कुछ शुरू करेगा। यह भी देखें [http://stackoverflow.com/questions/3320400/to-prevent-a-memory-leak-the-jdbc-driver-has-been-forcibly-unregistered)। –

+0

@ एम। डीनियम धन्यवाद, लेकिन मैंने पहले ही यह सुनिश्चित कर लिया है कि जेडीबीसी चालक केवल 'टोमकैट/lib' में है और एप्लिकेशन का' वेब-आईएनएफ/lib' – finchie

उत्तर

0

यह सामान्य है, ऐसा तब होता है जब आप टॉमकैट में गर्म तैनाती करते हैं। यह आपको उत्पादन में सामान्य रूप से कोई समस्या नहीं पहुंचाएगा क्योंकि आप आम तौर पर उत्पादन में गर्म तैनाती अद्यतन नहीं रखते हैं, आप बस इसके बजाय सर्वर को रोकें और पुनरारंभ करें।

+2

अन्य अनुप्रयोग हमारे उत्पादन टोमकैट पर तैनात नहीं हैं, कुछ बहुत बड़े हैं इस ऐप की तुलना में उपयोगकर्ताबेस! निश्चित रूप से मुझे सिर्फ एक ऐप को फिर से तैनात करने के लिए उत्पादन टोमकैट को पुनरारंभ करना नहीं चाहिए? क्या यह नहीं है कि टॉमकैट प्रबंधक ऐप क्या है? – finchie

1

मैं विषय here के बारे में एक लंबी चर्चा पाया। निष्कर्ष यह है कि यह एक "निश्चित आकार स्मृति रिसाव" बनाता है, यानी बाद में पुनर्वितरण स्मृति रिसाव में वृद्धि नहीं करेगा।
मेरे पास ओरेकल समर्थन पहुंच नहीं है, लेकिन चर्चा में उल्लिखित बग आईडी 16841748 (मई 2013, अब हल हो सकती है) है।

एक संभावित समाधान, वास्तव में एक बार डेटा स्रोत का उपयोग करें (कनेक्शन लेने, डमी क्वेरी, घनिष्ठ संबंध है) जब बिलाव कि कॉन्फ़िगर किया गया है एक कस्टम सर्वलेट के माध्यम से शुरू कर दिया है करने के लिए है करने के लिए "लोड-ऑन-स्टार्टअप" tomcat/conf/web.xml में। यह आपके वेब-ऐप के क्लास-लोडर के दायरे के बाहर ओरेकल ड्राइवर थ्रेड (FAQ को ड्राइवर थ्रेड के बारे में भी देखें), इस प्रकार "निश्चित आकार मेमोरी लीक" को रोकना चाहिए।

नोट है कि एक समान मुद्दा MySQL JDBC ड्राइवर के लिए मौजूद है, लेकिन एक decent solution है। ओरेकल जेडीबीसी चालक (मुझे नहीं पता) के हाल के संस्करण के लिए ऐसा समाधान मौजूद हो सकता है।

+0

"लोड-ऑन-स्टार्टअप" वर्कअराउंड सुझाव के लिए धन्यवाद - दुर्भाग्य से इसका कोई प्रभाव नहीं पड़ता है और स्मृति रिसाव चेतावनी अनावश्यक पर बनी रहती है। – finchie

+0

हम्म, इसे अपूर्ण कोड में देखा और पाया कि प्रत्येक oracle.jdbc.driver.PhysicalConnection एक "ब्लॉकसोर्स" धागा बनाता है। तो यह बताता है कि "लोड-ऑन-स्टार्टअप" क्यों काम नहीं करता है (मुझे लगता है कि यह ड्राइवर द्वारा शुरू किया गया एक सामान्य धागा था, प्रति कनेक्शन नहीं)। जैसा कि आपने अपने अद्यतन प्रश्न में वर्णित पुराने ड्राइवर संस्करण का उपयोग करना बेहतर समाधान की तरह दिखता है। – vanOekel

+1

मुझे लगता है कि चर्चा वास्तव में एक समान लेकिन असंबंधित मुद्दे के बारे में है, यही कारण है कि कामकाज का कोई प्रभाव नहीं पड़ा। इसके लिए ओरेकल दस्तावेज़ आईडी है, हालांकि, और एक पैच उपलब्ध है: [जेडीबीसी पतला चालक टॉमकैट के साथ थ्रेड थ्रेड (डॉक आईडी 1 9 0144 9 .1)] (https://support.oracle.com/epmos/faces/DocContentDisplay?id=1901449.1) – Mike

-1

यह समस्या केवल ओरेकल जेडीबीसी ड्राइवर (oracle.jdbc.driver.BlockSource.ThreadedCachingBlockSource.BlockReleaser) के साथ नहीं होती है।

3 पार्टी निर्भरता के किसी भी कुछ काम से बाहर ले जाने, फिर भी उनके लिए बिलाव लॉग चेतावनी संदेश को रोकने के थोड़ी देर के लिए एक डेमॉन धागा शुरू होता है।

इसके अलावा, यह समस्या Tomcat 8.5.X संस्करणों के साथ मौजूद है।

समाधान: मुझे समाधान के रूप में जो मिला वह वर्तमान धागे के लिए थ्रेड समूह प्राप्त करना और इसे बाधित करना है। यह सुनिश्चित करेगा कि टॉमकैट को बंद करने से पहले इसके सभी डिमन थ्रेड मारे गए हैं।

कोड नीचे "संदर्भडिस्टेड" विधि थ्रेड समूह समूह समूह = थ्रेड.current थ्रेड()। GetThreadGroup(); threadGroup.interrupt();

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