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

suga [E-MAIL ADDRESS DELETED]
2008年 8月 21日 (木) 00:34:58 JST


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