Memory JavaFX-内存消耗
我有一个巨大的JavaFX应用程序,主要使用FXML文件来创建视图,我注意到内存使用率很高,但已经忽略了一段时间。经过调查,我发现每个视图都消耗了大量的内存,但是,在关闭表单垃圾收集器之后,使用的内存被释放。 例如,滚动抛出一个包含约1000个元素的表视图[附屏幕截图],内存使用量从350 MB激增到780 MB 滚动列表视图时也会发生同样的情况,该列表视图显示了表视图的相同数据: 问题是,这正常吗?或者我可能做错了什么 更新 对于表视图,我正在执行以下操作以生成列:Memory JavaFX-内存消耗,memory,javafx,Memory,Javafx,我有一个巨大的JavaFX应用程序,主要使用FXML文件来创建视图,我注意到内存使用率很高,但已经忽略了一段时间。经过调查,我发现每个视图都消耗了大量的内存,但是,在关闭表单垃圾收集器之后,使用的内存被释放。 例如,滚动抛出一个包含约1000个元素的表视图[附屏幕截图],内存使用量从350 MB激增到780 MB 滚动列表视图时也会发生同样的情况,该列表视图显示了表视图的相同数据: 问题是,这正常吗?或者我可能做错了什么 更新 对于表视图,我正在执行以下操作以生成列: public st
public static <T> TableColumn<T, T> generateGraphicColumn(String title, Callback<TableColumn<T, T>, TableCell<T, T>> callback) {
TableColumn<T, T> column = generateColumn(title, null);
column.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<T, T>, ObservableValue<T>>() {
@Override
public ObservableValue<T> call(CellDataFeatures<T, T> param) {
SimpleObjectProperty<T> s = new SimpleObjectProperty<>();
s.setValue(param.getValue());
return s;
}
});
column.setCellFactory(callback);
return column;
}
public static <T> TableColumn<T, T> generateGraphicColumn(String title, Callback<TableColumn<T, T>, TableCell<T, T>> callback, double width) {
TableColumn<T, T> column = generateGraphicColumn(title, callback);
column.setMaxWidth(width);
column.setMinWidth(width);
return column;
}
public static <T,S> TableColumn<T, S> generateColumn(String title,
Callback<TableColumn.CellDataFeatures<T, S>, ObservableValue<S>> propertyValueFactory) {
TableColumn<T, S> column;
column = new TableColumn<>();
if (propertyValueFactory != null)
column.setCellValueFactory(propertyValueFactory);
column.setStyle(column.getStyle() + "-fx-alignment: BASELINE_CENTER;");
column.setText(title);
return column;
}
publicstatictablecolumn generateGraphicColumn(字符串标题,回调){
TableColumn column=generateColumn(标题,null);
column.setCellValueFactory(新回调(){
@凌驾
公共observeValue调用(CellDataFeatures参数){
SimpleObjectProperty s=新的SimpleObjectProperty();
s、 setValue(param.getValue());
返回s;
}
});
column.setCellFactory(回调);
返回列;
}
公共静态TableColumn generateGraphicColumn(字符串标题、回调、双宽度){
TableColumn column=generateGraphicColumn(标题,回调);
column.setMaxWidth(宽度);
列。设置最小宽度(宽度);
返回列;
}
公共静态表列generateColumn(字符串标题,
回调属性(值工厂){
表列;
column=新表column();
if(propertyValueFactory!=null)
column.setCellValueFactory(propertyValueFactory);
column.setStyle(column.getStyle()+“-fx对齐:基线_中心;”);
列.setText(标题);
返回列;
}
我使用的代码如下所示:
{ // status
TableColumn<Visit, Visit> column = TableViewUtilities.generateGraphicColumn(text("General.STATUS"),
new Callback<TableColumn<Visit, Visit>, TableCell<Visit, Visit>>() {
@Override
public TableCell<Visit, Visit> call(final TableColumn<Visit, Visit> param) {
final TableCell<Visit, Visit> cell = new TableCell<Visit, Visit>() {
@Override
public void updateItem(Visit item, boolean empty) {
super.updateItem(item, empty);
if (empty || getIndex() < 0) {
setGraphic(null);
setText(null);
return;
}
item = getTableView().getItems().get(getIndex());
Label label = new Label();
StackPane pane = new StackPane(label);
pane.setAlignment(Pos.CENTER);
label.setMaxWidth(10);
label.setMinWidth(10);
label.setMinHeight(30);
setText(item.getStatus().display());
String background = FXMLConstants .toHexString(ColorUtils.getVisitBackgroundColor(item));
pane.setStyle(String.format("-fx-background-color:%s;;", background));
setGraphic(pane);
setText(item.getStatus().display());
setStyle(getStyle() + "-fx-alignment: CENTER_LEFT;");
}
};
return cell;
}
}, 100);
column.setComparator(VisitCommonHelper.getCompByStatus());
tblVisits.getColumns().add(column);
}
{//status
TableColumn column=TableViewUtilities.generateGraphicColumn(文本(“General.STATUS”),
新回调函数(){
@凌驾
公共TableCell调用(最终TableColumn参数){
最终TableCell单元格=新TableCell(){
@凌驾
public void updateItem(访问项,布尔值为空){
super.updateItem(项,空);
if(空| | getIndex()<0){
设置图形(空);
setText(空);
返回;
}
item=getTableView().getItems().get(getIndex());
标签=新标签();
StackPane pane=新的StackPane(标签);
窗格设置对齐(位置中心);
标签。设置最大宽度(10);
标签设置最小宽度(10);
标签设置最小高度(30);
setText(item.getStatus().display());
String background=fxmlstants.toHexString(ColorUtils.getVisitBackgroundColor(item));
pane.setStyle(String.format(“-fx背景色:%s;;”,背景));
设置图形(窗格);
setText(item.getStatus().display());
setStyle(getStyle()+“-fx对齐:中间左;”;
}
};
返回单元;
}
}, 100);
setComparator(VisitCommonHelper.getCompByStatus());
tblVisits.getColumns().add(column);
}
您正在为每个非空单元格更新创建一个新的标签
和堆栈窗格
,这可能解释了堆使用率上升但可能被垃圾收集的原因
您可以尝试通过缓存节点来解决此问题(Label
在StackPane
中,在您的情况下)-仅创建一次:
final TableCell<Visit, Visit> cell = new TableCell<Visit, Visit>() {
private Label label;
private StackPane pane;
{
// This is the constructor of the anonymous class. Alternatively, you may choose to create the label and pane lazily the first time they're needed.
label = new Label();
pane = new StackPane(label);
pane.setAlignment(Pos.CENTER);
label.setMaxWidth(10);
label.setMinWidth(10);
label.setMinHeight(30);
}
@Override
public void updateItem(Visit item, boolean empty) {
super.updateItem(item, empty);
if (empty || getIndex() < 0) {
setGraphic(null);
setText(null);
return;
}
item = getTableView().getItems().get(getIndex());
setText(item.getStatus().display());
String background = FXMLConstants.toHexString(ColorUtils.getVisitBackgroundColor(item));
pane.setStyle(String.format("-fx-background-color:%s;;", background));
setGraphic(pane);
setText(item.getStatus().display());
setStyle(getStyle() + "-fx-alignment: CENTER_LEFT;");
}
};
final TableCell cell=new TableCell(){
自有品牌;
专用窗格;
{
//这是匿名类的构造函数。或者,您可以选择在第一次需要标签和窗格时延迟创建它们。
标签=新标签();
窗格=新的堆叠窗格(标签);
窗格设置对齐(位置中心);
标签。设置最大宽度(10);
标签设置最小宽度(10);
标签设置最小高度(30);
}
@凌驾
public void updateItem(访问项,布尔值为空){
super.updateItem(项,空);
if(空| | getIndex()<0){
设置图形(空);
setText(空);
返回;
}
item=getTableView().getItems().get(getIndex());
setText(item.getStatus().display());
String background=fxmlstants.toHexString(ColorUtils.getVisitBackgroundColor(item));
pane.setStyle(String.format(“-fx背景色:%s;;”,背景));
设置图形(窗格);
setText(item.getStatus().display());
setStyle(getStyle()+“-fx对齐:中间左;”;
}
};
另外-如果您从未设置标签的文本,标签有什么用途?单元格的
contentDisplay
是什么?是否显示了节点 这在很大程度上取决于表中行的数据类型以及显示它们的方式(自定义单元格工厂)。如果没有更多的上下文(即-用作数据模型的类和表上使用的任何单元格工厂),几乎无法判断它是否正常。@sillyfly请检查更新,我添加了一个我如何创建表列的示例您的解决方案确实解决了问题,,使用了标签,然后我设置了单元格文本[标签将被删除]、、一个问题