2012-07-06 13 views
7

मैं वर्तमान में टॉमकैट 7 (डब्ल्यू/ओरेकल जेडीके 7) पर किसी एप्लिकेशन के कुछ क्लास लोडर लीक की जांच कर रहा हूं। एक वर्ग जो वेब अनुप्रयोग वर्ग लोडर के लिए एक स्थिर संदर्भ रखता है (और इस प्रकार वर्ग लोडर को पुन: नियोजित/पुनरारंभ करने पर जारी नहीं किया जाता है) javax.xml.bind.DatatypeConverter है, जो सिस्टम क्लास लोडर में रहता है और theConverter फ़ील्ड के माध्यम से com.sun.xml.bind.DatatypeConverterImpl के माध्यम से एक स्थिर संदर्भ रखता है सूर्य के जैक्सब-इम्प्ले पैकेज से।javax.xml.bind.Datatype कनवर्टर कक्षा लोडर लीक?

क्या किसी ने कभी इस मुद्दे को पहले देखा है? कोई सुझाव (एप्लिकेशन शटडाउन पर स्थैतिक क्षेत्र को शून्य करने के लिए प्रतिबिंब का उपयोग करने के अलावा)?

+3

ब्लॉगपोस्ट के इस सेट में समस्या के बारे में अधिक जानकारी दी गई है: http://java.jiderhamn.se/category/classloader-leaks/ (इस मुद्दे के विवरण के लिए टेक्स्ट में 'जैक्सबी' की खोज करें ' वर्णन कर रहे हैं)। – Guus

उत्तर

12

जैसा कि यह निकला, मेरी निर्भरताओं में से एक (com.sun.jersey:jersey-json) com.sun.xml.bind:jaxb-impl में खींचा गया, जो सिस्टम क्लासलोडर -> एप्लिकेशन क्लासलोडर संदर्भ के लिए ज़िम्मेदार था। उस निर्भरता को छोड़कर इस मुद्दे को हल किया गया (जैसा कि जेडीके 7 एक समझदार जेएक्सबी कार्यान्वयन के साथ आता है, जिसे सिस्टम सीएल के भीतर संदर्भित किया जाएगा, जो ठीक है)।

0

बिलाव 8 मुद्दा बाद में वेब अनुप्रयोग पर चेतावनी के विकास के दौरान पुनर्वितरित:

org.apache.catalina.loader.WebappClassLoaderBase checkThreadLocalMapForLeaks 

SEVERE: The web application [rsnetlombard] created a ThreadLocal with key of type 
[com.sun.xml.bind.v2.ClassFactory$1] (value [[email protected]]) 
and a value of type [java.util.WeakHashMap] 
(value [{class java[email protected]525eec52}]) 
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. 

मैं VisualVM भीतर हीप डंप बनाने और उसे खोलें।

VisualVM क्वेरी द्वारा OQL टैब में नष्ट वेब अनुप्रयोग वर्ग लोडर लगता है:

select x from org.apache.catalina.loader.WebappClassLoader x where x.state.name.toString() == "DESTROYED" 

विजिटिंग में आपत्ति करने के लिए "instalce" टैब की अनुमति देने के कॉल में "संदर्भ अनुभाग" "निकटतम जीसी जड़ ढूंढें" लिंक ओर इशारा किया और कॉपी शाब्दिक प्रतिनिधित्व क्लिपबोर्ड ::

this  - value: org.apache.catalina.loader.WebappClassLoader #3 
<- <classLoader>  - class: com.sun.xml.bind.DatatypeConverterImpl, value: org.apache.catalina.loader.WebappClassLoader #3 
    <- <class>  - class: com.sun.xml.bind.DatatypeConverterImpl, value: com.sun.xml.bind.DatatypeConverterImpl class DatatypeConverterImpl 
    <- theConverter (sticky class)  - class: javax.xml.bind.DatatypeConverter, value: com.sun.xml.bind.DatatypeConverterImpl #1 

javax.xml.bind.DatatypeConverter जावा SE से है और उस वर्ग प्रणाली classloader द्वारा लोड (और इसलिए चिह्नित (sticky class))। लेकिन वेब एप्लिकेशन क्लासलोडर द्वारा लोड की गई कक्षा को इंगित करें।

com.sun.xml.bind.DatatypeConverterImpl के बारे में गुगलिंग इस SO पोस्ट की ओर जाता है।

आपूर्ति समाधान का कहना है कि com.sun.jersey:jersey-json पैकेज अनुरोध JAXB API कार्यान्वयन com.sun.xml.bind:jaxb-impl पैकेज :: से

$ mvn dependency:tree 
... 
[INFO] +- com.sun.jersey:jersey-json:jar:1.8:compile 
[INFO] | +- org.codehaus.jettison:jettison:jar:1.1:compile 
[INFO] | | \- stax:stax-api:jar:1.0.1:compile 
[INFO] | +- com.sun.xml.bind:jaxb-impl:jar:2.2.3-1:compile 
[INFO] | | \- javax.xml.bind:jaxb-api:jar:2.2.2:compile 
[INFO] | |  \- javax.xml.stream:stax-api:jar:1.0-2:compile 
[INFO] | +- org.codehaus.jackson:jackson-core-asl:jar:1.7.1:compile 
[INFO] | +- org.codehaus.jackson:jackson-mapper-asl:jar:1.7.1:compile 
[INFO] | +- org.codehaus.jackson:jackson-jaxrs:jar:1.7.1:compile 
[INFO] | \- org.codehaus.jackson:jackson-xc:jar:1.7.1:compile 

क्योंकि जावा 7 खुद JAXB कार्यान्वयन (JAXB RI इस तथ्य से) के साथ आता है हम com.sun.xml.bind:jaxb-impl पैकेज की जरूरत नहीं है। जोड़ें pom.xml का हिस्सा ::

<dependency> 
     <groupId>com.sun.jersey</groupId> 
     <artifactId>jersey-json</artifactId> 
     <version>${jersey.version}</version> 
     <exclusions> 
      <exclusion> 
       <groupId>com.sun.xml.bind</groupId> 
       <artifactId>jaxb-impl</artifactId> 
      </exclusion> 
     </exclusions> 
    </dependency> 

इसी क्रम पहुंच परिणाम परीक्षा में जल्दी में करने के लिए निकालना मैं बिलाव स्मृति ::

JAVA_OPTS="-Djava.awt.headless=true -Xmx212m -XX:+UseConcMarkSweepGC -XX:MaxPermSize=66m" 

Redeploing को कम/आवेदन 10 बार का उपयोग कर ::

के लिए कोई नहीं देना
select x from org.apache.catalina.loader.WebappClassLoader x where x.state.name.toString() == "DESTROYED" 

पुनर्वितरण के तहत "विजुअल जीसी" प्लग-इन ने PermGen क्लीनअप दिखाया।

पिछले विकास सेटअप के साथ चल रहा है कुछ ::

JAVA_OPTS="-Djava.awt.headless=true -Xmx512m -XX:+UseConcMarkSweepGC -XX:MaxPermSize=256m" 

4-5 redeploys जीवित रहने के लिए आवश्यकता होती है। बड़े परमजेन के लिए ओक्यूएल क्वेरी कई टोमकैट के WebappClassLoader प्रदान करती है लेकिन उदाहरणों की जांच करते हुए दिखाया गया है कि जीसी के लिए कोई रास्ता नहीं है और जब वे पर्मगेन पूर्ण हो जाते हैं तो उन्हें साफ़ कर दिया जाता है।

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