Seasar2 SAStruts Jdk6 tomcat7 の稼動環境で、コンテキストをアンデプロイしてもメモリリークが発生しておりPermGenを食いつぶす

【現象】
JDBCで使用しているクラス群がTOMCATのクラスローダーによって使用されたため、
コンテキストのアンデプロイを実施してもクラスが解放されないため、
PermGenを食いつぶしていた。

・jdk1.6.0_31
・apache-tomcat-7.0.27
・s2-framework-2.4.45
・sa-struts-1.0.4-sp9

調査にあたり、jvisualvm.exeでメモリ状況を確認する為、TomcatConfigurationに下記を追加。

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9092
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false


読み込み済みクラス数がGCを行っても減少せず、PermGenも増え続ける。休眠スレッド(黄色)がいつまでも解放されない。Find Leaksでコンテクストにリークが発見される。
(The following web applications were stopped (reloaded, undeployed), but their
classes from previous runs are still loaded in memory, thus causing a memory
leak (use a profiler to confirm):)

$あきらるのブログ
$あきらるのブログ
$あきらるのブログ
$あきらるのブログ




【対処】


JDBCドライバを%CATALINA_HOME%/lib以下に移動し、コンテキストでは参照しないように修正。
Mavenを使用していたため、Scopeを「Provided」に変更した。
その結果、アンデプロイ後、1分程度はリークするがその後クラスは破棄対象となる。

$あきらるのブログ
$あきらるのブログ

$あきらるのブログ




【参考】

stackoverflow.com
To prevent a memory leak, the JDBC Driver has been forcibly unregistered

JDBC 4.0の互換性のあるドライバがWebアプリケーションの/ WEB-INF/lib Webアプリの起動時に自身を自動登録する際の状況にある場合、順番に警告メッセージがこの種のにつながることができ、メモリリーク検出機能を持つバージョン6.0.24以降、Tomcatが船ServiceLoader APIを使用しますが、これは、Webアプリケーションのシャットダウン時に自身を自動登録を解除しませんでした。このメッセージは、Tomcatがすでにそれに応じて、メモリリークの防止処置を純粋に非公式取ったされています。

あなたは何ができますか?

1.これらの警告は無視してください。 Tomcatは、その仕事の権利をやっている。実際のバグはマーケットで、他人のコード(該当のJDBCドライバ)ではありません。 Tomcatが正しくその仕事をしたし、JDBCドライバのベンダーは、それはあなたがドライバをアップグレードすることができるように修理してもらうまで待つように幸せになる。

2.あなたはこれらの警告を気にされないように、6.0.23以前のバージョンをTomcatにダウングレードできます。しかし、それは静かにメモリリークが発生し続けます。わからないすべての後に知って良いことだその場合。メモリリークのそれらの種類は、Tomcat hotdeployments中にOutOfMemoryErrorが問題の背後にある主要な原因の1つです。

3.Tomcatの/ libフォルダにJDBCドライバを動かすと接続がドライバを管理するために、プールされたデータソースがあります。 TomcatのDBCPの組み込みが近い上に正しく登録解除ドライバをしないことに注意してください。バグDBCP-322も参照してください。 DBCPのプロジェクトは、しかし現在失速しています。私は、簡単な更新を期待しないだろう。あなたはむしろ良いし、DBCP、その仕事をやっている別の接続プールでDBCPを交換したいと思います。多分例BoneCPまたはTomcat JDBCプールのために?




【その他トライしNGだったもの】


途中、tomcat7のメモリリーク対応のオプションを試すも、関係なし。

-XX:+CMSParallelRemarkEnabled
-XX:+CMSClassUnloadingEnabled
-XX:+CMSPermGenSweepingEnabled

http://d.hatena.ne.jp/ryoasai/20100922/1285230566


jvisualvm.exeで確認すると、JPermGenの増加が緩やかになってきているように見えたので、
PermGenを増やしたが、100回くらい実行するとやはりPermGenが解放されず、やはりOutOfMemoryエラー。。。残念^^;

-XX:MaxPermSize=128m