2010-12-02 19 views
2

自分自身のスレッドを作成することによるメモリリークに関するTomcatの警告を解決しようとしています。 http://wiki.apache.org/tomcat/MemoryLeakProtectionは、スレッドを開始する前にmyThread.setContextClassLoader(null)に電話することを提案しています。setContextClassLoaderの意味

この呼び出しの意味は何ですか。 run()メソッドのコードは、アプリケーションからクラスを解決できますか?

答えて

10

はい、そうです。 Thread.getContextClassLoader()は、汎用フレームワークのためのメカニズムであり、クラスローダーツリーからさらにリソースをロードします。

Tomcatのクラスローダー階層を取ります。

 Bootstrap 
      | 
     System 
      | 
     Common 
    / \ 
    Webapp1 Webapp2 ... 

サーブレットまたはJSPフレームワークはCommonクラスローダに存在します。これらのフレームワークの1つがWebapp1からクラスパスリソースをロードすることであるならば、彼らは試みることができる:クラスローディングメカニックのみデリゲートがクラスローダのチェーンを呼び出すので、

getClass().getResource("/some/resource/in/webapp1"); // fail 

しかし、これは失敗します。これは、リソースをロードするために必要なすべてのフレームワークが代わりに行うことを意味します

Thread.currentThread().getContextClassLoader().getResource("/some/resource/in/webapp1"); 

とサーブレットコンテナがこのスレッドがそのコンテキストで実行されるたびにWebapp1クラスローダであることを確認します。したがって、スレッドのコンテキストクラスローダーは、事実上、フレームワークがクラ​​スを「間違った方向」からロードする方法です。

新しいスレッドを生成すると、そのスレッドはデフォルトで親のコンテキストクラスローダー(Webapp1クラスローダー)を取得します。その結果、Webapp1を停止した場合、tomcatはwebappにGCできるようになっていますが、Webapp1クラスローダーに残っている参照がある限り、これを行うことはできません。

Good article about context class loaders

+0

Thread.currentThread()。getContextClassLoader()を実行する前に、それらを設定する必要があります。私はコードにアクセスすることができないので、Tomcat Configurationを使ってそれらを設定するにはどうすればいいですか? – yapkm01