[Seasar-user:5886] [S2Container]S2FrameworkTestCase/UnitClassLoaderの実装について

kubo [E-MAIL ADDRESS DELETED]
2007年 1月 25日 (木) 13:29:36 JST


久保(jflute)です。

Teeda-1.0.3
S2Container-2.4.8
S2Dao-1.0.40
DBFlute-0.4.0
JUnit-3.8.1

S2FrameworkTestCase/UnitClassLoaderの実装について
確認したいことがあります。

現象と考察をご覧ください。


<現象>

S2TestCaseを継承したテストをEclipseのJUnitで一括実行すると
Memoryの使用量がMethod毎に(ほぼ定量的に)増えていって、
最終的にOutOfMemoryになる。OutOfMemoryのMessageは、“PermGen space”。

TestMethodはおよそ200。それぞれincludeするdiconを必要なものだけに
絞っているが、少し長続きするだけで最終的にはOutOfMemoryとなる。



<考察>

以前[Seasar-user:5229]で話題になっていたので、色々疑っては見たのですが、
どうもこれという原因を発見できていません。
(TestClassのInstance変数とかもML通りに疑いましたが基本SubClassが
 勝手に保持するようなInstance変数は存在していない)


そこで、S2FrameworkTestCaseで利用しているUnitClassLoaderについて
気になったので確認をさせて頂きたいです。

完全にClassLoader周りの仕組みを把握しているわけではないので、
間違った前提や思いや想像の説明があるかもしれないので、ご了承ください。
(遠慮なく指摘お願いします。仕組みを正しく理解したいという思いもあります)



UnitClassLoaderを見ると、親のClassLoaderをparentとして定義するのみで
他は特にMethodをoverrideしたりしていません。

そして、S2FrameworkTestCaseでは親のClassLoaderとして
sun.misc.Launcher$AppClassLoader(SystemClassLoader!?)を
UnitClassLoaderのparentに指定しています。

OutOfMemory対策でこのようになっていると認識していますが、
本当にこれで対策ができているのか確証が取れていません(理解できてない)。


UnitClassLoaderは、何もoverrideしていないので、そのままSuperClassの
ClassLoaderのMethodが呼び出されると思います。

その場合、ClassLoadingする際に、parentのClassLoaderが該当Classを
読み込んでしまわないでしょうか?
つまり、SystemClassLoaderがClassを読み込んでいないのでしょうか?

通常はその動きで問題ないかと思うのですが、Javassistを利用した場合に、
ProxyのClassがContextClassLoaderでLoadされますが、JUnit経由だと
それらProxyのClassたちは、最終的にSystemClassLoaderにLoadされて
しまわれてないか心配しています。
もし、そうだとすると、TestMethodの度にContainerが再作成されるため
毎回毎回実行分のProxyのClassたちがSystemClassLoaderに登録されて
Perm領域を圧迫するのではないかと考えます。


それとも、そのようなことはなく(少なくともOutOfMemoryの原因とは無関係)、
UnitClassLoaderの実装は現状ので正しいのでしょうか?
もしUnitClassLoaderは問題ないのであれば、その理由(仕組み)を
教えていただきたいのですがよろしいでしょうか?







-- 
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
kubo   <[E-MAIL ADDRESS DELETED]>
jflute <http://d.hatena.ne.jp/jflute>
株式会社ビルドシステム <http://www.buildsystem.co.jp>
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/





Seasar-user メーリングリストの案内