2015-01-23 20 views
13

जब मैं जावा 8 पर tomcat8 रोकने की कोशिश, मैं कुछ स्मृति त्रुटियों लीक मिलती है:Tomcat8 स्मृति रिसाव

org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [ROOT] appears to have started a thread named [Abandoned connection cleanup thread] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread: 
java.lang.Object.wait(Native Method) 
java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:142) 
com.mysql.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:40) 
23-Jan-2015 08:18:10.202 WARNING [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [ROOT] appears to have started a thread named [pool-5-thread-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread 


23-Jan-2015 08:18:10.205 SEVERE [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [ROOT] created a ThreadLocal with key of type [com.util.ThreadLocalProperties$1] (value [[email protected]]) and a value of type [java.util.Properties] (value [{}]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak. 

वर्ग ThreadLocalProperties है:

public class ThreadLocalProperties extends Properties { 

    private static final long serialVersionUID = -4260632266508618756L; 
    private final ThreadLocal<Properties> localProperties = new ThreadLocal<Properties>() { 
     @Override 
     protected Properties initialValue() { 
      return new Properties(); 
     } 
    }; 

    public ThreadLocalProperties(Properties properties) { 
     super(properties); 
    } 

    @Override 
    public String getProperty(String key) { 
     String localValue = localProperties.get().getProperty(key); 
     return localValue == null ? super.getProperty(key) : localValue; 
    } 

    @Override 
    public Object setProperty(String key, String value) { 
     return localProperties.get().setProperty(key, value); 
    } 

    public ThreadLocal<Properties> getThreadLocal() { 
     return localProperties; 
    } 
} 

और मैं शुरू करने और की तरह इसे रोकने के यह:

@WebListener() 
public class GeneralListener implements ServletContextListener { 

    ThreadLocalProperties threadLocalProperties = new ThreadLocalProperties(System.getProperties()); 

    @Override 
    public void contextDestroyed(ServletContextEvent arg0) { 
     threadLocalProperties.getThreadLocal().remove(); 
    } 

    @Override 
    public void contextInitialized(ServletContextEvent arg0) { 
     System.setProperties(threadLocalProperties); 
    } 
} 

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

क्या गलत है?

+0

http://docs.oracle.com/cd/E17952_01/connector-j-relnotes-en/news-5-1-23.html – David

उत्तर

9

चिंता करने की कोई बात नहीं है। यह एक मानक संदेश टॉमकैट आउटपुट है जब यह पता लगाता है कि एप्लिकेशन ने अपना Thread शुरू किया है या ThreadLocal बनाया है। यदि आप शट डाउन पर थ्रेड को समाप्त करते हैं और थ्रेडलोकल्स को हटाते हैं, जब उन्हें अब आवश्यकता नहीं होती है, तो कोई समस्या नहीं होगी।

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

मैं इस व्यवहार को देखा है, जब एक आवेदन ScheduledExecutor शुरू कर दिया है (लेकिन यह किसी भी अन्य Thread/TheadPool साथ क्या होगा) और contextDestroyed पर इसे बंद नहीं किया। तो जांचें कि क्या आप अपने धागे को एप्लिकेशन/सर्वर स्टॉप पर बंद कर रहे हैं।

अब आप अपने ठोस समस्या पर क्यों सर्वर बंद नहीं: JDBC ड्राइवर को एकमात्र के रूप में JVM में पंजीकृत हैं, और सभी webapps के साथ साझा कर रहे हैं। अधिक जानकारी here. आपकी समस्या का सबसे अच्छा समाधान MySQL ड्राइवर को टॉमकैट के /lib फ़ोल्डर में स्थानांतरित करना है। यदि आप ऐसा नहीं कर सकते हैं तो आप this आज़मा सकते हैं लेकिन यह वास्तविक समाधान की तुलना में हैक की तरह है।

+0

धन्यवाद। हाँ यह वास्तव में मदद की! दिलचस्प बात यह है कि अगर मैं अपने ऐप को अल्गो कहलाता हूं, और इसे server.xml <होस्ट नाम = "लोकलहोस्ट" ऐपबेस = "वेबपैप्स" अनपैकवार्स = "सत्य" ऑटोडिएट = "सत्य"> <संदर्भ docBase = "Algo" path = ""> WEB-INF/web.xml यह अल्गो फ़ोल्डर और रूट फ़ोल्डर दोनों में अल्गो युद्ध को तैनात करेगा! – Dejell

+2

mysql ड्राइवर को टॉमकैट/lib फ़ोल्डर में स्थानांतरित करना मेरे लिए काम नहीं करता था। – Neets

+0

क्या आपने ड्राइवर को/WEB-INF/lib से हटा दिया था? असल आपको यह संदेश मिलेगा यदि आपका एप्लिकेशन थ्रेड शुरू कर रहा है और उन्हें रोक नहीं रहा है। –

1

मुझे लगता है कि आपकी समस्या this के समान है। जब आप ऐप को फिर से तैनात करते हैं, तो अपाचे इसे अपने आप पर बढ़ता है जहां system.gc(); काम नहीं करते हैं और विकासशील चरण में कुछ पुनर्निर्माण के बाद स्थायी जेनरेट की गई जगह पूरी हो जाती है और आपको मेमोरी रिसाव त्रुटि मिलती है।

कृपया कुछ पुनर्वितरण के बाद अपने सर्वर को पुनरारंभ करना जारी रखें, इसलिए PermGen स्पेस को पुनरारंभ करने के साथ साफ़ किया जा सकता है।

या

एक आप भी यह सर्वर में PermGen अंतरिक्ष बदलकर हल कर सकते हैं। कृपया here पर जाएं।

मुझे आशा है कि यह आपकी मदद करेगा।

+0

मैं सर्वर को फिर से तैनात नहीं करता हूं। I ./shutdown और ./startup इसे। मुझे विश्वास है कि यह परम आकार संख्या को साफ़ करता है? – Dejell

+0

भी, जब मैंने tomcat8 को अतिरिक्त आकार की परिभाषा की कोशिश की तो मुझे एक चेतावनी मिली कि इसे अनदेखा किया जा रहा है – Dejell

+0

क्या आप शायद जावा 8 भी चला रहे हैं? मैं 100% निश्चित नहीं हूं, लेकिन मुझे लगता है कि उस रिलीज से परमजन स्पेस अप्रासंगिक हो गया है।मुझे कोई कारण नहीं दिखता कि टॉमकैट लॉगिंग कर रहे इन सूचनात्मक चेतावनी संदेशों में परमिट स्पेस के साथ कुछ भी नहीं है, और न ही वे इस बारे में चिंता करने के लिए कुछ भी हैं कि आप सर्वर को कड़ी मेहनत कर रहे हैं या नहीं। – Gimby

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