7

Tomcat 5.5 および Tomcat 6.0 サーバーでこの奇妙な問題が発生しています。Tomcat にインストールする 2 つの Web アプリケーションがあります。Tomcat を開始すると、これら 2 つの Web アプリケーションも同時に開始されますが、1 つのアプリケーションで初期化に失敗したために、1 つの Web アプリケーションが初期化に失敗することがあります。Tomcat 7.0 では、他のアプリケーションが初期化に失敗した場合でも、アプリケーションは正常に実行されます。

いくつかのデバッグの後、両方のアプリケーションの web-inf/lib フォルダーにある Crystal.jar という名前の jar が 1 つあることがわかりました。jar を tomcat の common/lib フォルダーに移動したところ、正常に動作し始めました。Tomcat 5.x および Tomcat 6.x バージョンではなく、Tomcat 7.0 で正常に動作する理由を知りたいです。これらのバージョン間でクラスローディング アーキテクチャに変更はありますか?

ありがとう

EDIT1:ライブラリは両方のアプリケーションの WEB-INF\lib ディレクトリの場所にあり、外部 DLL との依存関係はありません。ちょうど今、Tomcat 5.5 クラスローダ アーキテクチャについて読み、すべての Web アプリケーションに独自のクラス ローダがあることを知りました。WEB-INF\lib フォルダーと classes フォルダー内のライブラリーは、このクラスローダーにロードされます。共通ディレクトリに保存されているライブラリは、共有クラスローダーに配置されます。次に、このライブラリを Web アプリケーションの別のクラス ローダーに個別にロードする必要があります。これにより、1 つの Web アプリケーションが起動に失敗した場合でも、他の Web アプリケーションは独立して動作するはずです。それが私が奇妙に感じた理由であり、さらに調査する必要があります。

4

1 に答える 1

6

最後にこの問題の答えを見つけました

ライブラリ クラスがシステム クラスによって参照され、その期間を超えて存続する場合、既知の種類の PermGen メモリ リークが存在します。1 つの例は、Java が JDBC ドライバーまたはその他のサービスを検出し、それを「自動的に登録」する場合です。システム内でそれへの参照を保持しますが、クラス自体は Web アプリケーションに属しており、アプリケーションが停止したときにアンロードする必要がありますが、その参照のためにアンロードできません。そのような参照のすべてを簡単にクリアできるわけではありません。

このような場合の典型的な症状の 1 つは、このシステム機能に依存する最初の Web アプリケーションは成功するが、2 番目以降の Web アプリケーションは失敗することです (システムに登録されているサービスが最初の Web アプリケーションに属しており、クラスを参照できないため)。 2 番目のアプリケーションのクラスローダー、およびその逆)。

Tomcat 7 と Tomcat 6 の最近のバージョンでは、既定の構成で特定の既知の PermGen メモリ リークに対する保護が強化されています。

Tomcat 5.5 には、そのような保護はまったくありません。

編集いくつかの参照

http://people.apache.org/~markt/presentations/2010-08-05-Memory-Leaks-JavaOne-60mins.pdf http://people.apache.org/~markt/presentations/2010-11-04 -Memory-Leaks-60mins.pdf

http://eclipse.org/mat/

http://wiki.apache.org/tomcat/FAQ/Troubleshooting_and_Diagnostics http://wiki.apache.org/tomcat/MemoryLeakProtection

于 2012-06-10T19:20:53.960 に答える