Как исправить увеличение памяти при каждом обновлении данных таблицы - PullRequest
0 голосов
/ 06 января 2019

Объем памяти приложения javafx постоянно увеличивается. Это смутило меня, потому что я думал, что у меня утечка памяти в моем коде. я обнаружил, что память обновляется каждый раз при обновлении данных таблицы, нет новых объектов, просто обновляющих старые данные.

Цель следующего кода - воспроизвести ту же проблему

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 голосов
/ 21 января 2019

попробовал тот же код на Windows с той же версией JDK и все хорошо. Я собрал исполняемый jar на Ubuntu дважды, используя разные версии JDK, и проверил его на Windows и Ubuntu, что привело к одной и той же проблеме на обеих платформах. Так что в Ubuntu JDK возникает одна и та же проблема, независимо от того, какая версия JDK используется, я пока продолжу писать код для Windows, а позже попробую новую установку Ubuntu. спасибо за помощь

редактирование: после того, как поиск обнаружил некоторые сообщения об ошибках JDK-8161997 , JDK-8161911 кажется, что проблема, связанная с JavaFX, заключается в использовании аппаратного конвейера. после свежей установки Ubuntu 18.04 все работает нормально.

...