[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 メーリングリストの案内