It just creates a dumb tableView with a lot of lines.
Now take a profiler and run the first scenario:
Do not touch anything apart from the scroll thumb (vertical). Take it and play with it as long as you wish up and down. Fast and slow. If I take a memory snapshot right now, I can see that 171 instances of TableCell. are created.
Now run the test again, touch the scrollThumb as you like. But now, stop and try to scroll fast and slow with your mouse wheel. right up to the top and right down to the bottom (in fact the moment you touch the scrollWheel, new TableCell instances are created). If I take a memory snapshot, I can see up to 1371 instances of TableCell.
Is that normal? Between two behavior that are supposed to do the same, aka scroll through the grid. If I use my scrolling wheel of my mouse I end up with +960 objects of TableCell and +96 objects of TableRow.
Note also that those instances are strong-reachable and therefore, they can not be garbage collected.
PS: In the sample provided, try to modify the number of columns created, switch the limit to 50 instead of 10. You will see 900 TableCells, and after touching the mouse wheel, you will see 12 300 of them. Your application takes now 200MB of memory instead of 24MB at the very beginning.
Code:
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import javafx.util.Callback;
public class test3 extends Application {
private TableView<Person> table = new TableView<Person>();
final HBox hb = new HBox();
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
stage.setTitle("Table View Sample");
stage.setWidth(450);
stage.setHeight(550);
final Label label = new Label("Address Book");
label.setFont(new Font("Arial", 20));
table.setEditable(true);
table.getSelectionModel().setCellSelectionEnabled(true);
for (int i = 0; i < 10; ++i) {
TableColumn<Person, String> firstNameCol = new TableColumn<>("First Name");
firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName"));
firstNameCol.setCellFactory(new Callback<TableColumn<Person, String>, TableCell<Person, String>>() {
@Override
public TableCell<Person, String> call(TableColumn<Person, String> arg0) {
TableCell cell = new TableCell<>();
cell.setText("This is a test sample");
return cell;
}
});
table.getColumns().add(firstNameCol);
}
ObservableList<Person> templist = FXCollections.observableArrayList();
for (int i = 0; i < 5000; ++i) {
templist.add(new Person("Jacob", "Smith",
"jacob.smith@example.com"));
}
table.setItems(templist);
final VBox vbox = new VBox();
vbox.getChildren().addAll(table);
Scene scene = new Scene(vbox);
stage.setScene(scene);
stage.show();
}
public static class Person {
private final SimpleStringProperty firstName;
private final SimpleStringProperty lastName;
private final SimpleStringProperty email;
private Person(String fName, String lName, String email) {
this.firstName = new SimpleStringProperty(fName);
this.lastName = new SimpleStringProperty(lName);
this.email = new SimpleStringProperty(email);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String fName) {
firstName.set(fName);
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String fName) {
lastName.set(fName);
}
public String getEmail() {
return email.get();
}
public void setEmail(String fName) {
email.set(fName);
}
}
}
Now take a profiler and run the first scenario:
Do not touch anything apart from the scroll thumb (vertical). Take it and play with it as long as you wish up and down. Fast and slow. If I take a memory snapshot right now, I can see that 171 instances of TableCell. are created.
Now run the test again, touch the scrollThumb as you like. But now, stop and try to scroll fast and slow with your mouse wheel. right up to the top and right down to the bottom (in fact the moment you touch the scrollWheel, new TableCell instances are created). If I take a memory snapshot, I can see up to 1371 instances of TableCell.
Is that normal? Between two behavior that are supposed to do the same, aka scroll through the grid. If I use my scrolling wheel of my mouse I end up with +960 objects of TableCell and +96 objects of TableRow.
Note also that those instances are strong-reachable and therefore, they can not be garbage collected.
PS: In the sample provided, try to modify the number of columns created, switch the limit to 50 instead of 10. You will see 900 TableCells, and after touching the mouse wheel, you will see 12 300 of them. Your application takes now 200MB of memory instead of 24MB at the very beginning.
Code:
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import javafx.util.Callback;
public class test3 extends Application {
private TableView<Person> table = new TableView<Person>();
final HBox hb = new HBox();
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
stage.setTitle("Table View Sample");
stage.setWidth(450);
stage.setHeight(550);
final Label label = new Label("Address Book");
label.setFont(new Font("Arial", 20));
table.setEditable(true);
table.getSelectionModel().setCellSelectionEnabled(true);
for (int i = 0; i < 10; ++i) {
TableColumn<Person, String> firstNameCol = new TableColumn<>("First Name");
firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName"));
firstNameCol.setCellFactory(new Callback<TableColumn<Person, String>, TableCell<Person, String>>() {
@Override
public TableCell<Person, String> call(TableColumn<Person, String> arg0) {
TableCell cell = new TableCell<>();
cell.setText("This is a test sample");
return cell;
}
});
table.getColumns().add(firstNameCol);
}
ObservableList<Person> templist = FXCollections.observableArrayList();
for (int i = 0; i < 5000; ++i) {
templist.add(new Person("Jacob", "Smith",
"jacob.smith@example.com"));
}
table.setItems(templist);
final VBox vbox = new VBox();
vbox.getChildren().addAll(table);
Scene scene = new Scene(vbox);
stage.setScene(scene);
stage.show();
}
public static class Person {
private final SimpleStringProperty firstName;
private final SimpleStringProperty lastName;
private final SimpleStringProperty email;
private Person(String fName, String lName, String email) {
this.firstName = new SimpleStringProperty(fName);
this.lastName = new SimpleStringProperty(lName);
this.email = new SimpleStringProperty(email);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String fName) {
firstName.set(fName);
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String fName) {
lastName.set(fName);
}
public String getEmail() {
return email.get();
}
public void setEmail(String fName) {
email.set(fName);
}
}
}