torutkのブログ

ソフトウェア・エンジニアのブログ

JavaFXのアニメーションで繰り返しを無制限にするとメモリリークの兆候が…(続)

昨日JavaFXのアニメーションで繰り返しを無制限にするとメモリリークの兆候が… - torutkのブログの続きです。

アナログ時計の実現方法として、RotateTransitionを作成し、cycleCountを無限に設定してplay()を呼ぶことで、時計の針を回転させるアニメーションを繰り返し実行させていました。骨子は次のようなコードになります。

RotateTransition rt = new RotateTransition(Duration.seconds(60), secondHand);
  :
rt.setCycleCount(Animation.INDEFINITE);
rt.play();

cycleCountの指定を無限から有限(1回=1周)にして、1周回るごとにRotateTransitionを再作成してアニメーションを実行するようにしました。

RotateTransition rt = new RotateTransition(Duration.seconds(60), secondHand);
  :
rt.setCycleCount(1);
rt.setOnFinished(//... RotateTransitionを再作成し、playを呼ぶ);
rt.play();

アニメーション(ここではRotateTransition)のplay()メソッドは非同期なので、終了のタイミングを拾うために、setOnFinishedでイベントハンドラーを登録します。イベントハンドラーの中でRotateTransitionインスタンスを再度作成し、そのplay()を呼びます。

骨子は上述のコードですが、実際のソースコードは次です。
http://www.torutk.com/projects/swe/repository/github_analogclock/revisions/4d67e44d630d2eed6f641803d2bc1138d5b744ed/entry/AnalogClockSvg/src/analogclocksvg/AnalogClockController.java

ヒープの推移を見ると、経過時間に対してフルGCの発生が減っています。

RotateTransitionの再作成はせずに、playを繰り返し呼ぶだけにしたところ、次のようなヒープ使用状況になりました。メモリリーク対処としては、一定期間でplayの処理を終え、新たにplayを呼び出すことがポイントのようです。