2010年8月22日日曜日

エスケープ解析とfinalize

ARMについて調べているときに、エスケープ解析でスタックに割り付けられたオブジェクトのfinalizeがちゃんと呼ばれるなら、確実なリソースの開放が出来るんじゃないかと思って調べてみた。

まずエスケープ解析でスタックに割り当てられるようなオブジェクトを作って動作を確認する。
その後、そのオブジェクトでfinalizeをoverrideしてみたところ、スタックに割り当てられなくなったっぽい。
(GCログで確認)

finalizeを実行するスレッドを確認すると、通常通りFinalizerスレッドで実行されていた。これだと、非同期に実行されるのでメソッドを抜けたときに開放できないし(finalizeが実行されるまで待つなら出来るが…)、Finalizerスレッドからfinalizeを呼び出すためにオブジェクトが漏れてしまっている。
Javaの理論と実践: ガベージコレクションとパフォーマンスにもそのようなことが書いてある。

エスケープ解析はJVMの最適化オプションであってVMが満たすべき仕様ではないからか、VM仕様に書かれてはいないようだが、エスケープ解析の論文を適当に幾つか読むと、finalizeをoverrideしていたらどうしても漏れる(Global Escape)から最初からエスケープ解析する対象から省いてしまうらしい。
ただ、java.lang.ref.Finalizer$FinalizerThreadを使うこと自体もSunのJVM実装仕様だったはずなので、他のVMだったら違うかもしれない。



0 件のコメント:

コメントを投稿