gpt4 book ai didi

绘制图表时 JavaFX WeakReference 内存泄漏

转载 作者:行者123 更新时间:2023-11-30 10:43:05 25 4
gpt4 key购买 nike

我遇到了内存泄漏,我无法在我的代码中修复它。场景:用户打开一个新窗口,其中绘制了一个图表(在本例中为折线图)。但是当窗口关闭时,java.lang.ref.WeakReferencejavafx.beans.property.BooleanPropertyBase$Listener 留在内存中。它们的数量与绘制的数据点 (XYChart.Data) 完全对应。我只是不知道如何摆脱它们。在我的代码中,许多此类窗口频繁打开和关闭,每个图表有 10k-100k 数据点,内存很快就会被填满。

我确定我犯了一些愚蠢的错误,但我就是找不到它。将不胜感激!

示例代码:

import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Button;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class Test extends Application {

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Application.launch(Test.class, args);
}

@Override
public void start(final Stage primaryStage) {
primaryStage.setTitle("Hello World");
Group root = new Group();
Scene scene = new Scene(root, 300, 250, Color.LIGHTGREEN);
Button btn = new Button();
btn.setLayoutX(100);
btn.setLayoutY(80);
btn.setText("Create stage");
btn.setOnAction(new EventHandler<ActionEvent>() {

public void handle(ActionEvent event) {
new CreateStage();
primaryStage.toFront();

}
});
root.getChildren().add(btn);
primaryStage.setScene(scene);
primaryStage.show();
}
}

class CreateStage {

public CreateStage() {
Stage stage = new Stage();
stage.setTitle("Line Chart Sample");
//Basic Chart attributes
NumberAxis xAxis = new NumberAxis();
NumberAxis yAxis = new NumberAxis();
xAxis.setLabel("RT [minutes]");
yAxis.setLabel("Intensity");
LineChart<Number, Number> linechart = new LineChart(xAxis, yAxis);

XYChart.Series newSeries = new XYChart.Series();

List<XYChart.Data> list = new ArrayList<>();
//just fill the chart with data points
for (int j = 0; j < 10000; j++) {
float intensity = j;
float currentRT = j;

list.add(new XYChart.Data(currentRT, intensity));
}
newSeries.getData().addAll(list);

// add new Series
linechart.getData().add(newSeries);

Scene scene = new Scene(linechart,800,600);


stage.setScene(scene);
stage.show();
}
}

最佳答案

我能够解决问题。呼唤

series.getData().clear();

关闭窗口时在每个 XYChart.Series 上消除内存泄漏。javafx.scene.layout.CornerRadiicom.sun.javafx.sg.prism.NGRegionjavafx.scene.layout.Background 仍然保留在内存中,但最终会被垃圾收集并且不会堆积。

固定代码如下:

import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.ScatterChart;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Button;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class Test extends Application {

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Application.launch(Test.class, args);
}

@Override
public void start(final Stage primaryStage) {
primaryStage.setTitle("Hello World");
Group root = new Group();
Scene scene = new Scene(root, 300, 250, Color.LIGHTGREEN);
Button btn = new Button();
btn.setLayoutX(100);
btn.setLayoutY(80);
btn.setText("Create stage");
btn.setOnAction(new EventHandler<ActionEvent>() {

public void handle(ActionEvent event) {
CreateStage();
primaryStage.toFront();

}
});
root.getChildren().add(btn);
primaryStage.setScene(scene);
primaryStage.show();
}

public void CreateStage() {

Stage stage = new Stage();
stage.setTitle("Line Chart Sample");
//Basic Chart attributes
NumberAxis xAxis = new NumberAxis();
NumberAxis yAxis = new NumberAxis();
xAxis.setLabel("RT [minutes]");
yAxis.setLabel("Intensity");

//linechart.getData().clear();
LineChart<Number, Number> linechart = new LineChart(xAxis, yAxis);

XYChart.Series newSeries = new XYChart.Series();

List<XYChart.Data> list = new ArrayList<>();
//just fill the chart with data points
for (int j = 0; j < 10000; j++) {
float intensity = j;
float currentRT = j;

list.add(new XYChart.Data(currentRT, intensity));
}
newSeries.getData().addAll(list);

// add new Series
linechart.getData().add(newSeries);

Scene scene = new Scene(linechart, 800, 600);

stage.setScene(scene);
stage.show();

//this fixes it
stage.setOnCloseRequest(event -> {
for (XYChart.Series series : linechart.getData()) {
series.getData().clear();
}

});

}
}

感谢@fabian 为我指明了正确的方向。

关于绘制图表时 JavaFX WeakReference 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37883426/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com