[mayaa-user:941] Re: Tomcat7 + Mayaa1.1.28 + HotSpot VMにてload関数でPermGenを無駄に消費してしまうようです

suga [E-MAIL ADDRESS DELETED]
2012年 10月 9日 (火) 23:05:02 JST


suga です。


2012/10/9 Susumu ISHIGAMI <susumu.ishigami @ gmail.com>
> TODOが記載されていますが、将来的にはここでServletContextを使わず、
> Fileパスを返すようにする想定であったのでしょうか?
> それならばその時にこの件は解消されるのかもしれませんね。

おおむねそういうところです。
ひとまずの問題回避としては、タイムスタンプを取得できない場合は常に最小値を返す実装にすることを考えています。
その場合はタイムスタンプチェックが有効にならないので、それをどうしようかというところを
思考中です。

現実装では、webapp の下にはスクリプトを置かず、absolutePath を使う方法で
取得するようにすれば一応問題を回避できるはずです。
http://mayaa.seasar.org/documentation/template_path.html

# 石上さんはご存知でしょうけど


> また、昨日のメールに記載させていただいた、再現アプリケーションについてはいかが致しましょうか?
> メモリの使用量やクラスロード数を画面に表示するようにしていますので、確認のお役に立てるのではないかと思います。

ありがとうございます。
私宛に直接送って頂けると助かります。


--
suga ( ko.suga @ gmail.com )


2012/10/9 Susumu ISHIGAMI <susumu.ishigami @ gmail.com>
>
> sugaさん
> 素早いレスポンスありがとうございます。
>
> もう一つ参考になりそうな情報を記載するのを忘れていましたので追記します。
>
> /mayaa1.1.28_blank/src-impl/org/seasar/mayaa/impl/source/ApplicationSourceDescriptor.java
> の 80行目
>     protected URL getURL() {
>         String path = _fileSourceDescriptor.getRealPath();
>         if (StringUtil.isEmpty(path)) {
>             path = "/";
>         }
>         // TODO ここにServletContextクラスが登場しないようにする
>         ServletContext context =
>             (ServletContext) getApplicationScope().getUnderlyingContext();
>         try {
>             return context.getResource(path);
>         } catch (MalformedURLException e) {
>             throw new IllegalStateException("invalid: " + path);
>         }
>     }
>
> この
>             return context.getResource(path);
> が、TomcatとJettyで異なった箇所です。
>
> TODOが記載されていますが、将来的にはここでServletContextを使わず、
> Fileパスを返すようにする想定であったのでしょうか?
> それならばその時にこの件は解消されるのかもしれませんね。
>
> 安易な提案ですが、context.getRealPathを使えば絶対パスが取得できると思いますので
> そちら経由で調整することもできるかもしれません。
> リモートからリソースを取ってくるような特殊な構成ではこの方法は使えないでしょうから、
> 特殊ケースは考慮する必要はあると思います。
>
> また、昨日のメールに記載させていただいた、再現アプリケーションについてはいかが致しましょうか?
> メモリの使用量やクラスロード数を画面に表示するようにしていますので、確認のお役に立てるのではないかと思います。
>
> よろしくお願い致します。
>
> 2012年10月9日 5:38 suga <ko.suga @ gmail.com>:
> > sugaです。
> >
> > 調査およびご報告ありがとうございます。
> >
> > 対応方法を考えますのでしばらくお待ちください。
> > ちょっと時間がかかるかもしれません。
> >
> > --
> > suga ( ko.suga @ gmail.com )
> >
> >
> > 2012/10/8 Susumu ISHIGAMI <susumu.ishigami @ gmail.com>
> >>
> >> Mayaa開発者様
> >> おせわになっております。石上です。
> >>
> >> Tomcat7 + Mayaa1.1.28 + HotSpot VMにおいて
> >> load関数やexecプロセッサーで外部jsファイルを開くと、
> >> リクエストを受け付けるごとにPermGen領域を使用してしまう現象を確認しましたので報告致します。
> >>
> >> 具体的には、
> >> defaule.mayaaに
> >>         <m:beforeRender><![CDATA[
> >>                 load("/util.mjs");
> >>         ]]></m:beforeRender>
> >>
> >> と記述したとすると、
> >>
> >> org.seasar.mayaa.impl.cycle.script.rhino.SourceCompiledScriptImpl.compileFromSource(Context,
> >> SourceDescriptor)
> >> にて、
> >> source.getTimestamp()
> >> で、ファイルのタイムスタンプを調べています。
> >>
> >>
> >> org.seasar.mayaa.impl.source.ApplicationSourceDescriptor.getTimestamp()の実装を読むと、
> >>     public Date getTimestamp() {
> >>         if (canUseFile()) {
> >>             return _fileSourceDescriptor.getTimestamp();
> >>         }
> >>         return new Date(IOUtil.getLastModified(_url));
> >>     }
> >> のようになっています。
> >>
> >> ここで、canUseFile()はfalseを返します。
> >> これは内部の
> >>     if (_fileSourceDescriptor.exists() == false) {
> >> とい行で、
> >>
> >>      public boolean exists() {
> >>         prepareFile();
> >>         return (_file != null) && _file.exists();
> >>     }
> >> の中、
> >>
> >> file.exists()
> >> はfalseを返します。
> >>
> >> fileが"/util.mjs"のようにルート始まりになっているためです。
> >>
> >> getTimestamp内で、canUseFile()がfalseを返してしまうので、
> >> return _fileSourceDescriptor.getTimestamp();
> >> ではなく、
> >> return new Date(IOUtil.getLastModified(_url));
> >> が実行されます。
> >>
> >> IOUtil.getLastModifiedは
> >>     public static long getLastModified(URL url) {
> >>         File file = getFile(url);
> >>         if (file != null) {
> >>             return file.lastModified();
> >>         }
> >>         return System.currentTimeMillis();
> >>     }
> >> という実装になっていますので、
> >> _urlのプロトコルが"file:///""でなければ、タイムスタンプを取得できず、常に現在時刻を返す仕様のようです。
> >>
> >> ここで、
> >> Eclipse J2EE Preview (Jettyベース)では、
> >> _urlがfile://で始まっているのですが、
> >> Tomcat7で試したところ、
> >> jndi://になっていました。
> >>
> >> ここから先はRhino内部へ行ってしまうため詳細に追えていませんが、スクリプトをコンパイルすると、
> >> クラスが一つロードされるのではないかと思います。
> >>
> >> HotSpot VMでは、クラスロードはPermGen領域に行われ、この領域は、いわゆるYoung GCでは
> >> クリアされないため、いずれPermGen使用率が100%となり、Full GCが発生してしまうと思います。
> >>
> >> Tomcat6でも同様の現象を確認したため、おそらく同じようになっているのだと思います。
> >> Tomcat5以前は試していないのでわかりません。
> >>
> >> うまく整理できず、込み入った報告となってしまいましい申し訳ありません。
> >> 当初自分が複雑なことをやっているためかと思ったのですが、
> >> サンプルベースのシンプルなプロジェクトでも上記現象を再現しましたので、やはり報告せねばと思いました。
> >> 小さいプロジェクトですが、zipにかためて4KB程の容量になってしまうため、MLに送信することがためらわれます。
> >> 送付先をご指定頂ければ、送付させて頂くことができます。
> >>
> >> 自分は、この問題のために、プロジェクト全体でload関数を使うことをやめ、mayaaファイルにスクリプトファイルを
> >> ベタ書きすることで対処していますが、load関数はマニュアルにも記載されている一般的な方法であると思いますので、
> >> ご確認頂けると良いかと思います。
> >>
> >> 万が一自分の勘違いによる的はずれな報告であったら、申し訳ありません。
> >>
> >> 以上、何卒よろしくお願い致します。
> >>
> >>
> >> --
> >> /**
> >> * @twitter  http://twitter,com/susumuis
> >> * @blog     http://d.hatena.ne.jp/s-ishigami/
> >> * @github  http://github.com/susumuishigami
> >> * @gmail   susumu.ishigami @ gmail.com
> >> */
> >> Susumu ISHIGAMI
> >> _______________________________________________
> >> mayaa-user mailing list
> >> mayaa-user @ ml.seasar.org
> >> https://ml.seasar.org/mailman/listinfo/mayaa-user
> >
> >
> >
> > _______________________________________________
> > mayaa-user mailing list
> > mayaa-user @ ml.seasar.org
> > https://ml.seasar.org/mailman/listinfo/mayaa-user
>
>
>
> --
> /**
> * Java Web Programmer
> * interested in Mayaa PostgreSQL Tomcat Pivotal Tracker
> * @twitter  http://twitter,com/susumuis
> * @blog     http://d.hatena.ne.jp/s-ishigami/
> * @github  http://github.com/susumuishigami
> * @gmail   susumu.ishigami @ gmail.com
> */
> Susumu ISHIGAMI


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