Optimizar la pérdida de memoria en JavaFX
javafx-8 (2)
He escrito un código para que las letras aparezcan y vuelen mientras las escribo. El problema consume mucha memoria.
Ya lo optimicé un poco
-
Compartir el objeto de
path
y actualizar sus parámetros en oyentes. - Llamar a gc cada vez que se imprime una nueva carta
Pero aún usa mucha memoria, ¿alguna idea sobre cómo reducir su utilización de memoria?
Gracias por adelantado.
package sample;
import javafx.animation.PathTransition;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.LineTo;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
Pane root = new Pane();
Scene scene = new Scene(root);
root.setCache(false);
primaryStage.setTitle("Hello World");
primaryStage.setScene(scene);
Path path = new Path();
root.widthProperty().addListener((observableValue, oldSceneWidth, newSceneWidth) -> SetPathElements(path, root));
root.heightProperty().addListener((observableValue, oldSceneWidth, newSceneWidth) -> SetPathElements(path, root));
Duration duration = Duration.millis(1000);
scene.setOnKeyPressed(event -> {
System.gc();
Text textNode = new Text(event.getText());
textNode.setFont(Font.font(50));
textNode.setFill(Color.ORANGE);
root.getChildren().add(textNode);
PathTransition pathTransition = new PathTransition();
pathTransition.setDuration(duration);
pathTransition.setPath(path);
pathTransition.setCycleCount(1);
pathTransition.setNode(textNode);
pathTransition.setOnFinished(event1 -> {
root.getChildren().remove(textNode);
pathTransition.setNode(null);
pathTransition.setPath(null);
textNode.setFont(null);
textNode.setFill(null);
});
pathTransition.play();
});
primaryStage.show();
}
private void SetPathElements(Path path, Pane root) {
path.getElements().clear();
double w = root.getWidth();
double h = root.getHeight();
path.getElements().add(new MoveTo(w / 2, h));
path.getElements().add(new LineTo(w / 2, -40));
}
}
EDITAR # 1
Sistema operativo: Arch Linux Plataforma de 64 bits: Intel i7-3a generación, 8 GB de RAM IDE: Intellij JDK: 1.8.0_102
Prueba de fuga: después de escribir alrededor de 100 caracteres, saltó de 50 MB a 1.3 GB
EDITAR # 2
Verifiqué el tamaño del montón usando jvisualvm e indica que el montón se expande mucho, pero la porción utilizada no supera los ~ 50 MB
Hay una pérdida de memoria en JavaFX con Mesa> = 11.0 (es decir, cualquier distribución actualizada de Linux).
Los desarrolladores de JavaFX dicen que es un error en Mesa, pero no pude encontrar un informe de error en Mesa (ni pude archivar uno, ya que no sé cómo reproducirlo fuera de JavaFX).
Las únicas soluciones a partir de ahora son:
1. Use un Linux anterior (la clave es tener Mesa 10 o inferior)
2. Use una GPU NVidia: tienen su propia implementación de OpenGL y no confían en Mesa.
3. Use Windows.
Actualización (noviembre de 2016)
Este problema parece haberse resuelto en las versiones más recientes de Mesa y / o X.org.
La actualización a Mesa 13.0 y X.org> = 1.18.4
debería
resolver este problema.
Enlaces relacionados:
La actualización a Mesa 13.0.4 no soluciona el problema, pero hay una solución alternativa.
Si el programa se ejecuta con el
-Dprism.order=j2d
o
-Dprism.order=sw
VM, el motor de renderizado JavaFX no usa OpenGL y no se produce la fuga.
Por supuesto, el rendimiento de la aplicación se degrada significativamente en este caso.