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

kubo [E-MAIL ADDRESS DELETED]
2007年 1月 25日 (木) 21:44:40 JST


久保です。

小林さんありがとうございます。

> S2AOP は,エンハンスしたクラスのバイトコード(byte[])を
> コンテキストクラスローダーの ClassLoader#defineClass() で
> ロードします.このメソッドは protected なのでリフレクション
> 経由で呼び出します.
> org.seasar.framework.aop.javassist.AbstractGenerator の
> toClass(ClassLoader, CtClass) メソッドがそれです.
> 
> そして,ClassLoader#defineClass() の実装は loadClass() と
> 異なり,親クラスローダーへ委譲しません.
> そのクラスローダー自身にロードされます.

なるほど...
すいません、そこまで追えてませんでした。

それならば、確かにEnhanceされたClassは全てUnitClassLoaderですね。


> System.out.println(dao.getClass().getClassLoader());
> 
> すれば,どのクラスローダーからロードされているか
> 確認できます.

確認してみました。
確かに仰るとおりでした。



色々探してみた結果、SystemClassLoaderでLoadされたClassが
UnitClassLoaderでLoadされたClassを保持している箇所がありました。
(初期化時に大量のDaoをSetterInjectionするObjectです)

そのSetterInjectionを止めて、内部でContainerを保持して
DaoのInstanceは都度getComponentして取得するようにしました。
(destoryMethodを定義してContainerへの参照は終了時に破棄)

するとかなりTestの実行Speedは早くなり、先に進むようになったのですが、
今度は 「OutOfMemoryError: java heap」 が発生するように
なってしまいました。
メソッド呼び出しの度に一定の割合でメモリ使用量が増加しています。
[Seasar-user:5233]のスレッドを参考にすると、
こちらの原因もやはり、

  SystemClassLoaderでLoadされたClassが
  UnitClassLoaderでLoadされたClassを保持

なのでしょうか...


現状、

ある AOPの存在しないSingletonのComponent「Aaa」に
ある AOPの存在するSingletonのDao-Component 「BbbDao」を
SetterInjectionさせている箇所がありました。

これらのTest-Method上でのClassLoaderを見てみると、

Aaa   :sun.misc.Launcher$AppClassLoader
BbbDao:org.seasar.framework.unit.UnitClassLoader

でした。

これは先述した

  SystemClassLoaderでLoadされたClassが
  UnitClassLoaderでLoadされたClassを保持

に該当するケースに見えますが、
このような実装は多く存在します。



確認をしたいのですが、

Dao(EnhanceされるClass)のInstanceを
他のSingleton-Component(EnhanceされないClass)のInstanceに
SetterInjectionさせてはいけないものでしょうか?
(Seasarの根本的なClass設計に関わる部分です)



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





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