昨日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を呼び出すことがポイントのようです。