java - JavaFX scrolling table update performance degrades over time -
i have tableview shows last n items, new items @ top, remove items bottom etc... appears happening cpu load increases on time point other x applications on same machine become sluggish.
platform details: redhat 6.7, 32 bit, java 1.8u40
things i've tried
- introduced runlater() - original code updated observable list non-fx thread - apparently wrong
- optimize - place new runnables on javafx application thread if there isn't update in progress
- optimize -bulk updates observable list rather individual adds
- used jvisual vm indentify memory leaks, couldn't find anything.
- i've tried recreate
- windows 7 (on metal) - jdk 8u40 64 bit => not occur
- ubuntu 16.04 jdk 8u40 64 bit (inside vm vmwgfx) => not occur
- ubuntu 16.04 openjdk + openjfx latest (8u91) (on metal) => does occur
jvisual vm - redhat 6u7 (32bit) on newish hardware
jvisual vm - ubuntu 16.04 (64bit) on old hardware (2008 imac)
this issue part of larger app, i've isolated smaller example below. makes other apps sluggish after couple of minutes, on redhat 6u7 platform.
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); }); } } }
questions
- is issue way i'm updating table or underlying bug?
- any more efficient ways update table?
Comments
Post a Comment