-
Bug
-
Resolution: Fixed
-
P3
-
8
From John Hendrikx's mail:
I'm having trouble creating a reproducable test case.
There seems to be more going on -- if I open and close the Pane involved several times, eventually some of them will start to be GC'd (but never all, unless I disable the animation). I've used VisualVM to inspect the Pane involved, and here is what it says is keeping it alive (clearly something animation related atleast):
this - value: hs.mediasystem.screens.playback.PlaybackOverlayPane #1
<- this$0 - class: javafx.scene.Node$8, value: hs.mediasystem.screens.playback.PlaybackOverlayPane #1
<- target - class: com.sun.scenario.animation.shared.InterpolationInterval$DoubleInterpolationInterval, value: javafx.scene.Node$8 #149
<- [0] - class: com.sun.scenario.animation.shared.InterpolationInterval[], value: com.sun.scenario.animation.shared.InterpolationInterval$DoubleInterpolationInterval #28
<- [0] - class: com.sun.scenario.animation.shared.InterpolationInterval[][], value: com.sun.scenario.animation.shared.InterpolationInterval[] #10 (3 items)
<- interval - class: com.sun.scenario.animation.shared.GeneralClipInterpolator, value: com.sun.scenario.animation.shared.InterpolationInterval[][] #16 (1 items)
<- clipInterpolator - class: com.sun.scenario.animation.shared.TimelineClipCore, value: com.sun.scenario.animation.shared.GeneralClipInterpolator #16
<- clipCore - class: javafx.animation.Timeline, value: com.sun.scenario.animation.shared.TimelineClipCore #19
<- this$0 - class: javafx.animation.Animation$1, value: javafx.animation.Timeline #19
<- [5] - class: com.sun.scenario.animation.shared.PulseReceiver[], value: javafx.animation.Animation$1 #19
<- receivers - class: com.sun.javafx.tk.quantum.MasterTimer, value: com.sun.scenario.animation.shared.PulseReceiver[] #1 (7 items)
<- this$0 - class: com.sun.scenario.animation.AbstractMasterTimer$MainLoop, value: com.sun.javafx.tk.quantum.MasterTimer #1
<- animationRunnable - class: com.sun.javafx.tk.quantum.QuantumToolkit, value: com.sun.scenario.animation.AbstractMasterTimer$MainLoop #1
<- this$0 (JNI global) - class: com.sun.javafx.tk.quantum.QuantumToolkit$14, value: com.sun.javafx.tk.quantum.QuantumToolkit #1
If that is enough for a bugreport, I'll create one. A naive simple test case which spawns several panes and animations was unable to reproduce this issue I'm having:
package hs.mediasystem;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.beans.value.WeakChangeListener;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Duration;
public class TimelineGCProblem extends Application {
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage stage) throws Exception {
StackPane rootPane = new StackPane();
Scene scene = new Scene(rootPane);
stage.setScene(scene);
stage.show();
new Thread() {
@Override
public void run() {
for(;;) {
Platform.runLater(new Runnable() {
@Override
public void run() {
rootPane.getChildren().setAll(new FadeInPane());
}
});
try {
System.gc();
Thread.sleep(1500);
System.gc();
}
catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
public static class FadeInPane extends StackPane {
private final Timeline fadeInSustainAndFadeOut = new Timeline(
new KeyFrame(Duration.seconds(0)),
new KeyFrame(Duration.seconds(1), new KeyValue(opacityProperty(), 1.0)),
new KeyFrame(Duration.seconds(6), new KeyValue(opacityProperty(), 1.0)),
new KeyFrame(Duration.seconds(8), new KeyValue(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();
}
}
};
public FadeInPane() {
sceneProperty().addListener(new WeakChangeListener<>(sceneChangeListener));
setStyle("background-color: red");
getChildren().add(new Button("Hi"));
}
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("FadeInPane finalized");
}
}
}
I'm having trouble creating a reproducable test case.
There seems to be more going on -- if I open and close the Pane involved several times, eventually some of them will start to be GC'd (but never all, unless I disable the animation). I've used VisualVM to inspect the Pane involved, and here is what it says is keeping it alive (clearly something animation related atleast):
this - value: hs.mediasystem.screens.playback.PlaybackOverlayPane #1
<- this$0 - class: javafx.scene.Node$8, value: hs.mediasystem.screens.playback.PlaybackOverlayPane #1
<- target - class: com.sun.scenario.animation.shared.InterpolationInterval$DoubleInterpolationInterval, value: javafx.scene.Node$8 #149
<- [0] - class: com.sun.scenario.animation.shared.InterpolationInterval[], value: com.sun.scenario.animation.shared.InterpolationInterval$DoubleInterpolationInterval #28
<- [0] - class: com.sun.scenario.animation.shared.InterpolationInterval[][], value: com.sun.scenario.animation.shared.InterpolationInterval[] #10 (3 items)
<- interval - class: com.sun.scenario.animation.shared.GeneralClipInterpolator, value: com.sun.scenario.animation.shared.InterpolationInterval[][] #16 (1 items)
<- clipInterpolator - class: com.sun.scenario.animation.shared.TimelineClipCore, value: com.sun.scenario.animation.shared.GeneralClipInterpolator #16
<- clipCore - class: javafx.animation.Timeline, value: com.sun.scenario.animation.shared.TimelineClipCore #19
<- this$0 - class: javafx.animation.Animation$1, value: javafx.animation.Timeline #19
<- [5] - class: com.sun.scenario.animation.shared.PulseReceiver[], value: javafx.animation.Animation$1 #19
<- receivers - class: com.sun.javafx.tk.quantum.MasterTimer, value: com.sun.scenario.animation.shared.PulseReceiver[] #1 (7 items)
<- this$0 - class: com.sun.scenario.animation.AbstractMasterTimer$MainLoop, value: com.sun.javafx.tk.quantum.MasterTimer #1
<- animationRunnable - class: com.sun.javafx.tk.quantum.QuantumToolkit, value: com.sun.scenario.animation.AbstractMasterTimer$MainLoop #1
<- this$0 (JNI global) - class: com.sun.javafx.tk.quantum.QuantumToolkit$14, value: com.sun.javafx.tk.quantum.QuantumToolkit #1
If that is enough for a bugreport, I'll create one. A naive simple test case which spawns several panes and animations was unable to reproduce this issue I'm having:
package hs.mediasystem;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.beans.value.WeakChangeListener;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Duration;
public class TimelineGCProblem extends Application {
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage stage) throws Exception {
StackPane rootPane = new StackPane();
Scene scene = new Scene(rootPane);
stage.setScene(scene);
stage.show();
new Thread() {
@Override
public void run() {
for(;;) {
Platform.runLater(new Runnable() {
@Override
public void run() {
rootPane.getChildren().setAll(new FadeInPane());
}
});
try {
System.gc();
Thread.sleep(1500);
System.gc();
}
catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
public static class FadeInPane extends StackPane {
private final Timeline fadeInSustainAndFadeOut = new Timeline(
new KeyFrame(Duration.seconds(0)),
new KeyFrame(Duration.seconds(1), new KeyValue(opacityProperty(), 1.0)),
new KeyFrame(Duration.seconds(6), new KeyValue(opacityProperty(), 1.0)),
new KeyFrame(Duration.seconds(8), new KeyValue(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();
}
}
};
public FadeInPane() {
sceneProperty().addListener(new WeakChangeListener<>(sceneChangeListener));
setStyle("background-color: red");
getChildren().add(new Button("Hi"));
}
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("FadeInPane finalized");
}
}
}
- relates to
-
JDK-8097954 [Timeline, Javadoc]: Javadocs should be more clear on references made and other things
-
- Resolved
-