每次更新tableview数据时如何解决内存增加的问题

时间:2019-01-05 23:24:29

标签: java javafx tableview

我的javafx应用程序内存随着时间的推移不断增加。这让我感到困惑,因为我认为我的代码内存泄漏。 我发现每次更新tableview数据时内存都会增加,没有任何新对象只是更新旧数据。

以下代码的目的是重现相同的问题

public class TableViewSample extends Application {

    private boolean running = false;

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) {
        Scene scene = new Scene(new Group());
        stage.setTitle("Table View Sample");

        TableView<Foo> table = new TableView<>();
        ObservableList<Foo> data = FXCollections.observableArrayList(
                new Foo(0, 0, 0, 0), new Foo(0, 0, 0, 0), new Foo(0, 0, 0, 0),
                new Foo(0, 0, 0, 0), new Foo(0, 0, 0, 0), new Foo(0, 0, 0, 0),
                new Foo(0, 0, 0, 0), new Foo(0, 0, 0, 0), new Foo(0, 0, 0, 0),
                new Foo(0, 0, 0, 0), new Foo(0, 0, 0, 0), new Foo(0, 0, 0, 0),
                new Foo(0, 0, 0, 0), new Foo(0, 0, 0, 0), new Foo(0, 0, 0, 0),
                new Foo(0, 0, 0, 0), new Foo(0, 0, 0, 0), new Foo(0, 0, 0, 0),
                new Foo(0, 0, 0, 0), new Foo(0, 0, 0, 0), new Foo(0, 0, 0, 0),
                new Foo(0, 0, 0, 0), new Foo(0, 0, 0, 0), new Foo(0, 0, 0, 0),
                new Foo(0, 0, 0, 0), new Foo(0, 0, 0, 0), new Foo(0, 0, 0, 0)
        );
        Random random = new Random();

        TableColumn<Foo, Integer> num1Col = new TableColumn<>("num1");
        num1Col.setCellValueFactory(new PropertyValueFactory<>("num1"));
        TableColumn<Foo, Integer> num2Col = new TableColumn<>("num2");
        num2Col.setCellValueFactory(new PropertyValueFactory<>("num2"));
        TableColumn<Foo, Integer> num3Col = new TableColumn<>("num3");
        num3Col.setCellValueFactory(new PropertyValueFactory<>("num3"));
        TableColumn<Foo, Integer> num4Col = new TableColumn<>("num4");
        num4Col.setCellValueFactory(new PropertyValueFactory<>("num4"));

        table.setItems(data);
        table.getColumns().addAll(num1Col, num2Col, num3Col, num4Col);

        Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(1), event -> {
            for (Foo foo : data) {
                foo.setNum1(random.nextInt(1000));
                foo.setNum2(random.nextInt(1000));
                foo.setNum3(random.nextInt(1000));
                foo.setNum4(random.nextInt(1000));
            }
        }));
        timeline.setCycleCount(Timeline.INDEFINITE);

        Button btn = new Button("start");
        btn.setOnAction(event -> {
            if (running) {
                timeline.stop();
                running = false;
                btn.setText("start");
            } else {
                timeline.play();
                running = true;
                btn.setText("stop");
            }
            event.consume();
        });

        VBox vbox = new VBox();
        vbox.getChildren().addAll(btn, table);
        ((Group) scene.getRoot()).getChildren().add(vbox);

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

    }

    public static class Foo {
        private SimpleIntegerProperty num1;
        private SimpleIntegerProperty num2;
        private SimpleIntegerProperty num3;
        private SimpleIntegerProperty num4;


        public Foo(int num1, int num2, int num3, int num4) {
            this.num1 = new SimpleIntegerProperty(num1);
            this.num2 = new SimpleIntegerProperty(num2);
            this.num3 = new SimpleIntegerProperty(num3);
            this.num4 = new SimpleIntegerProperty(num4);
        }

        public int getNum1() {
            return num1.get();
        }

        public SimpleIntegerProperty num1Property() {
            return num1;
        }

        public void setNum1(int num1) {
            this.num1.set(num1);
        }

        public int getNum2() {
            return num2.get();
        }

        public SimpleIntegerProperty num2Property() {
            return num2;
        }

        public void setNum2(int num2) {
            this.num2.set(num2);
        }

        public int getNum3() {
            return num3.get();
        }

        public SimpleIntegerProperty num3Property() {
            return num3;
        }

        public void setNum3(int num3) {
            this.num3.set(num3);
        }

        public int getNum4() {
            return num4.get();
        }

        public SimpleIntegerProperty num4Property() {
            return num4;
        }

        public void setNum4(int num4) {
            this.num4.set(num4);
        }
    }
}

我做错什么了,如何解决此内存增加的问题?

1 个答案:

答案 0 :(得分:1)

在具有相同jdk版本的Windows上品尝了相同的代码,一切都很好。 我已经使用不同的jdk版本在ubuntu上构建了两次可执行jar,并在Windows和ubuntu上对其进行了测试,并且在两个平台上都导致了相同的问题。因此,无论使用什么版本的jdk,ubuntu jdk都会产生相同的问题,我现在将继续在Windows上进行编码,稍后将尝试重新安装ubuntu。感谢您的帮助

编辑: 经过一番搜索发现一些相关的错误报告JDK-8161997之后,JDK-8161911似乎与JavaFX有关的问题正在使用硬件管道。 重新安装ubuntu 18.04后,一切正常。