2012-07-06 13 views
7

私は現在、Tomcat 7(Oracle JDK 7)のアプリケーションのクラスローダーリークを調べています。 Webアプリケーションクラスローダーへの静的参照を保持する(したがって、再デプロイ/再起動時にクラスローダーが解放されないようにする)クラスは、システムクラスローダーに存在し、theConverterフィールドを介して静的参照をcom.sun.xml.bind.DatatypeConverterImplに保持しますSunのjaxb-implパッケージから入手できます。クラスローダをリークしているjavax.xml.bind.DatatypeConverter?

誰もこの問題を以前に観察したことがありますか?任意の提案(アプリケーションシャットダウン時にリフレクションを使用して静的フィールドをnullにすることを除く)

+3

詳細はブログ記事のこのセットに与えられる:http://java.jiderhamn.se/category/classloader-leaks/(あなた」問題の説明のためのテキストの「JAXB」を検索再記述)。 – Guus

答えて

12

私の依存関係の1つ(com.sun.jersey:jersey-json)は、com.sun.xml.bind:jaxb-implを取得しました。これは、System Classloader - > Application Classloaderの参照を担当していました。この依存関係を除いて、問題が解決されました(JDK 7には適切なJAXB実装が付属しています。これはSystem CL内で参照されます)。開発中に、後続のWebアプリケーションの再デプロイに警告

0

Tomcatの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タブで破壊されたWebアプリケーションのクラスローダを見つける:

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

訪問は、コールが「参照 セクション」とコピーに「最も近いGCのルートを検索する」許可「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をテキスト表現は、Java SEやシステムクラスローダ (およびその(sticky class)マーク)によってロードされ、そのクラスからです。しかし、Webアプリケーションクラスローダーによってロードされたクラスを指します。

グーグル約com.sun.xml.bind.DatatypeConverterImplは、このSOのポストにつながります。

提供されるソリューションは、Java 7には独自のJAXB実装(事実によってJAXB RI)が付属していますので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 

我々は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> 

ために迅速な結果に到達テストに私はTomcatのメモリを減らす::

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" 

「Visual GC」プラグインの再利用でPermGenクリーンアップが表示されます。以前の開発のセットアップを実行

は4-5再デプロイを生き残るために何か::

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

が必要です。大きなPermGenのためのOQLクエリは、いくつかのTomcatのWebappClassLoader を与えるが、インスタンスGCへのパスが存在しないことを示すとPermGenがいっぱい になったときに、それらが洗浄さを調べます。問題の

関連する問題