[mayaa-user:682] Re: カスタムタグのreleaseメソッド呼び出しのタイミングについて

佐竹雅央 [E-MAIL ADDRESS DELETED]
2008年 8月 24日 (日) 14:18:37 JST


佐竹です。

ご回答ありがとうございます。
返信が遅くなりすみません。

仕組みについて確認しました。
(タグはプーリングしていないハズという色眼鏡で読んでいたために
勘違いしていたようで、今読み直してみると確かにそうですね。お恥ずかしい。)

ただ、今の仕様ですとStrutsのLinkTagは再利用されれば必ずヌルポが
発生しそうなものですが、実際には極低確率でしか発生していません。
それでマルチスレッド利用でのタイミングの問題を疑ったのですが。
これは、ソフト参照によるキャッシュが再利用前に消えているのでしょうか・・・
余裕があるときに確認してみたいと思います。

ところで

> これは Mayaa 実装時に見落としていたことで、少なくとも JSP 2.0 以降では
> release() 後の再利用を想定しない実装の方が良さそうに思います。
> また、その場合でも JSP 1.2 の範囲内なので、release() は再利用しない
> ときに呼ぶ方が良さそうですね。

とのことですが、改良版を提供していただくことは可能でしょうか?


以上、よろしくお願いいたします。

2008/08/21 0:34 suga <[E-MAIL ADDRESS DELETED]>:
> suga です。
>
> On 8/20/08, 佐竹雅央 <[E-MAIL ADDRESS DELETED]> wrote:
>> 早速ですが、JSPカスタムタグのプーリングとreleaseについて、
>> 確認させていただきたいことがあります。
>>
>> カスタムタグのrelease()メソッドですが、ガベージ直前にしか
>> 呼ばないことになっていますが、Mayaaの JspProcessor は、
>> タグの使用後に、毎回これを呼んでしまっている気がします。
>>
>> そのため、release()の中で普段はnullになることの無いフィールドも
>> 含めてnullクリアしているタグが、プーリング・再利用されると、
>> NullPointerExceptionを発生させてしまいます。
>>
>> (具体的にはStrutsのLinkTagで発生しました)
>
> 「GC 直前にしか呼ばない」のではなく、「GC 前には呼ばれることを
> JSP コンパイラが保証する」のが正しいです。
>
> 念のため調べてみたところ、どうも JSP 1.2 のときには release() 後も
> 再利用することを想定していた図が、JSP 2.0 ではそうでないように
> 変わっているようです。
>
> http://suga.parfe.jp/td/index.cgi?date=20080821#p01
>
> これは Mayaa 実装時に見落としていたことで、少なくとも JSP 2.0 以降では
> release() 後の再利用を想定しない実装の方が良さそうに思います。
> また、その場合でも JSP 1.2 の範囲内なので、release() は再利用しない
> ときに呼ぶ方が良さそうですね。
>
>
>> ただ、過去ログなどからMayaaではTagのプーリングをしていない
>> ような記述もありましたのでソースを呼んでみましたところ、
>
> これはおそらく Mayaa の Processor についての記述と混同されたのでは
> ないでしょうか。Processor は単一インスタンスで動作します。
>
>
>> 0.Tag(と属性)に紐付くPoolがないので空Poolを作成(※初回のみ)
>> 1.PoolからTagを取り出そうとして空なので新しいTagを作成
>> 2.Tagを使用
>> (略)
>> 3.Tag#release()を呼ぶ
>> 4.TagをPoolに戻す
>> 5.TryCatchFinallyなTagかチェックするためにPoolからTag取り出し
>> 6.チェックに使ったTagはPoolに戻さない
>>
>> という具合になっているように見受けられました。
>> (TryCatchFinallyであるTagの場合は少しタイミングが変わるようですが)
>>
>> 4でPoolに入れるものの5でスグに取り出して、
>> そのまま戻さないので使い捨て同然なのですが、
>> 別スレッドが4,5の間に滑り込んでrelease呼び出し後の
>> Tagを使ってしまうことはありませんか?
>
> こちらは間違いです。
>
> TryCatchFinally であれば doFinally 後に Pool へ戻し、そうでなければ
> doEnd 後に Pool に戻します。
> もちろん Pool に戻す前に TryCatchFinally であるかどうかを確認します。
>
>
> --
> suga ( [E-MAIL ADDRESS DELETED] )
> _______________________________________________
> mayaa-user mailing list
> [E-MAIL ADDRESS DELETED]
> https://ml.seasar.org/mailman/listinfo/mayaa-user
>


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