[Seasar-user:19289] Re: ライブラリの格納先について
Koichi Kobayashi
[E-MAIL ADDRESS DELETED]
2010年 2月 11日 (木) 15:00:01 JST
小林 (koichik) です.
Date: Wed, 10 Feb 2010 12:00:58 +0000
From: "奥野 守" <[E-MAIL ADDRESS DELETED]>
To: [E-MAIL ADDRESS DELETED]
Subject: [Seasar-user:19277] Re: ライブラリの格納先について
> パターン2:
> ・[ライブラリ]をWEB-INF/libにのみ格納する。
> (jboss配下には格納しない)
>
> 結果2:
> ・hotdeploy(再配備)時、クラスのアンロードが行われるものの、
> 数回再配備を繰り返すとOutOfMemoryError(PermGen space)
> # アンロードできているクラス/できていないクラスの詳細は
> まだ確認できていない状態です。
Dolteng で作成した SAStruts + S2JDBC のアプリと
Tomcat 6.0.24 の組み合わせを以下の手順で確認しました.
1.Tomcat の JVM 起動オプションに -verbose:class を指定し,
VisualJVM を起動しておく.
2.Tomcat を起動して SAStruts + S2JDBC アプリの
画面を開く.
3.VisualJVM で Heap Dump を取得し,Tomcat の
WebappClassLoader のインスタンスに該当 Web アプリを
ロードした WebappClassLoader が含まれていることを確認.
(jarNames フィールドの内容から判断できます)
4.管理画面から SAStrtus + S2JDBC アプリをアンデプロイする.
5.すぐにはアンロードされないので,VisualJVM から
GC を何度か発生させる.
6.VisualJVM の Heap Dump を取得し,Tomcat の
WebappClassLoader のインスタンスに該当 Web アプリを
ロードした WebappClassLoader が含まれていない (GC された)
ことを確認.
7.-verbose:class のログから,ロードされたクラスと
アンロードされたクラスのマッチングを行い,該当アプリに
含まれるクラスが残ってないことを確認.
以上の結果から,SAStruts + S2JDBC の最低限の
アプリケーションは Tomcat から問題なくアンデプロイ
できています.
そちらのアプリ + JBoss でも同じように確認してみてください.
ロードされたクラスとアンロードされたクラスのマッチングは
次のようなクラスを作って行ったので参考にどうぞ.
# こういう時に LL 使わないと格好悪い気がするけどいいのだ.
ログを保存して実行すると,ロードされたのにアンロード
されていないクラスがコンソールに出力されます.
ファイルのパスとエンコーディングは実際に合わせてください.
public class ClassLeakTest extends TestCase {
Pattern loadPattern = Pattern.compile("\\[Loaded (\\S+) from (.*)]");
Pattern unloadPattern = Pattern.compile("\\[Unloading class (\\S+)]");
public void test() throws Exception {
BufferedReader r = new BufferedReader(new InputStreamReader(
new FileInputStream("log.txt"),
"Shift_JIS"));
Map<String, String> map = new HashMap<String, String>();
String line = null;
while ((line = r.readLine()) != null) {
Matcher matcher = loadPattern.matcher(line);
if (matcher.matches()) {
String className = matcher.group(1);
String from = matcher.group(2);
map.put(className, from);
continue;
}
matcher = unloadPattern.matcher(line);
if (matcher.matches()) {
String className = matcher.group(1);
map.remove(className);
}
}
for (String className: map.keySet()) {
System.out.println(className + " from " + map.get(className));
}
}
}
--
<component name="koichik">
<property name="fullName">"Koichi Kobayashi"</property>
<property name="email">"[E-MAIL ADDRESS DELETED]"</property>
<property name="blog">"http://d.hatena.ne.jp/koichik"</property>
</component>
Seasar-user メーリングリストの案内