簡體   English   中英

JavaFX滾動表更新性能會隨着時間的推移而降低

[英]JavaFX scrolling table update performance degrades over time

我有一個顯示最后N個項目的TableView,頂部的新項目,從底部刪除項目等...似乎正在發生的事情是CPU負載隨着時間的推移而增加,以指示同一台機器上的其他X應用程序變得遲緩。

平台細節:Redhat 6.7,32位,Java 1.8u40

我嘗試過的事情

  • 引入了runLater() - 原始代碼從非FX線程更新了可觀察列表 - 顯然這是錯誤的
  • 優化 - 如果尚未進行更新,則僅在JavaFX應用程序線程上放置新的Runnables
  • 優化-bulk更新Observable列表而不是單獨添加
  • 使用jvisual VM來識別任何內存泄漏,找不到任何東西。
  • 我試圖重新創造這個
    • Windows 7(在金屬上) - JDK 8u40 64位=>不會發生
    • Ubuntu 16.04 JDK 8u40 64位(在帶有vmwgfx的VM內)=>不會發生
    • Ubuntu 16.04 OpenJDK + OpenJFX最新版(8u91)(金屬上)=> 確實發生

JVisual VM - 新硬件上的Redhat 6u7(32位)

Redhat 6u7

JVisual VM - 舊硬件上的Ubuntu 16.04(64位)(2008 iMac)

英特爾iMac上的Ubuntu 16.04

這個問題是較大的應用程序的一部分,但我已將其作為下面的一個較小的例子。 這使得其他應用程序在幾分鍾后變得緩慢,但僅限於Redhat 6u7平台。

public class TableUpdater extends Application {
    private int maxItems = 30;
    private AtomicBoolean pending = new AtomicBoolean();
    public class Thing {
        private String foo;
        public Thing(String foo) {
            this.foo = foo;
        }
        public String getFoo() {
            return foo;
        }
        @Override
        public int hashCode() {
            return foo.hashCode();
        }
        @Override
        public boolean equals(Object obj) {
            if (! (obj instanceof Thing)) {
                return false;
            }
            return ((Thing)obj).foo.equals(foo);
        }
    }

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

    private int counter = 0;
    private ObservableList<Thing> data;
    private List<Thing> itemsToAdd = Collections.synchronizedList(new ArrayList<Thing>());

    @Override
    public void start(Stage primaryStage) throws Exception {
        TableView<Thing> table = new TableView<>();
        data = FXCollections.observableArrayList();
        table.setItems(data);

        TableColumn<Thing, String> fooCol = new TableColumn<>("Foo");
        fooCol.setCellValueFactory(new PropertyValueFactory<Thing, String>("foo"));
        table.getColumns().addAll(fooCol);

        Executors.newScheduledThreadPool(1).scheduleAtFixedRate(() -> {
            add(new Thing(String.format("%08d", counter++)));
        }, 0, 2, TimeUnit.MILLISECONDS);

        primaryStage.setScene(new Scene(table));
        primaryStage.setWidth(400);
        primaryStage.setHeight(400);
        primaryStage.show();
    }

    private void add(Thing thing) {
        itemsToAdd.add(thing);

        if (!pending.getAndSet(true)) {
            Platform.runLater(() -> {
                synchronized (itemsToAdd) {
                    Collections.reverse(itemsToAdd);
                    data.addAll(0, itemsToAdd);
                    itemsToAdd.clear();
                }
                if (data.size() > maxItems) {
                    data.remove(maxItems, data.size());
                }
                pending.set(false);
            });
        }
    }
}

問題

  • 這個問題與我更新表或底層錯誤的方式有關嗎?
  • 更新表的更有效方法?

嘗試使用G1GC垃圾收集器。 我有一個類似但不完全相同的問題(tableview中的大量持久對象),這是通過使用G1GC解決的。

java XX:+UseG1GC

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM