Problem with Timeline keeping references around

John Hendrikx hjohn at xs4all.nl
Tue Oct 15 15:35:23 PDT 2013


Hi List,

I just submitted https://javafx-jira.kenai.com/browse/RT-33600 which is 
asking for the Timeline JavaDocs to be more clear on when and where hard 
references are being created and how to properly clean up after 
oneself.  Most of the docs hardly mention anything when it comes to 
references causing memory leaks, and Timeline is no exception.

However, apart from the docs not really discussing this topic, I 
actually cannot get proper cleanup to work at all when working with a 
Timeline.

If my Timeline is referencing properties from a StackPane and the 
Timeline was run atleast once, I cannot figure out how to get this Pane 
to be gc'd.  Calling stop() and even doing getKeyFrames().clear() 
doesn't help.  I'm sure it must be the Timeline because if I remove the 
KeyFrames that access the StackPane, it will get gc'd properly.  If I 
never run the animation, it also gets gc'd properly.

See code below.  The System.outs will occur exactly as expected when the 
StackPane becomes part of the Scene and when it is removed from the 
Scene.  I call stop() on my Timeline and even clear its KeyFrames, but 
the StackPane refuses to be gc'd (even after hitting the GC button I 
created for this occasion dozens of times).

Not calling playFromStart() or not using the KeyFrames that refer to 
detailsOverlay.opacityProperty() will solve the problem, and the 
finalize() System.out will occur usually after the first or second time 
I press my GC button.

Anything else I can try or is this a bug?
--John

public class PlaybackOverlayPane extends StackPane {
   private final Timeline fadeInSustainAndFadeOut = new Timeline(
     new KeyFrame(Duration.seconds(0)),
     new KeyFrame(Duration.seconds(1), new 
KeyValue(detailsOverlay.opacityProperty(), 1.0)),
     new KeyFrame(Duration.seconds(6), new 
KeyValue(detailsOverlay.opacityProperty(), 1.0)),
     new KeyFrame(Duration.seconds(9), new 
KeyValue(detailsOverlay.opacityProperty(), 0.0))
   );

   private final ChangeListener<Scene> sceneChangeListener = new 
ChangeListener<Scene>() {
     @Override
     public void changed(ObservableValue<? extends Scene> observable, 
Scene oldValue, Scene newValue) {
       if(newValue != null) {
         System.out.println(">>> Starting fadeIn anim");
         fadeInSustainAndFadeOut.playFromStart();
       }
       else {
         System.out.println(">>> Stopping fadeIn anim");
         fadeInSustainAndFadeOut.stop();
         fadeInSustainAndFadeOut.getKeyFrames().clear();
         fadeInSustainAndFadeOut.stop();
       }
     }
   };

   private final GridPane detailsOverlay = GridPaneUtil.create(new 
double[] {5, 20, 5, 65, 5}, new double[] {45, 50, 5});

  ...

   @Override
   protected void finalize() throws Throwable {
     super.finalize();
     System.out.println(">>> Finalized " + this);
   }
}


More information about the openjfx-dev mailing list