我正在尝试更好地理解并改善 Swing 应用程序的内存使用情况。
用户每次需要搜索要销售的产品时往往都会重复打开一个屏幕。此屏幕显示一个包含大量产品的 jtable,如下图所示。
问题是,当我不断打开和关闭此屏幕时,堆内存不断增加,并且垃圾收集器似乎无法工作(可能是因为我的对象没有被释放)。
我使用 java VisualVM 来检查哪些对象最消耗堆空间,下面的屏幕截图显示了它。
我认为这些 char[] 和 string 对象是由于 JTable 而创建的。
当我关闭屏幕时,我会执行以下操作
jTable1 = null;
data = null; //(arraylist where I stored the data from the database)
System.gc();
有人知道我可能会错过什么吗?除了将引用设置为 null 之外,还有其他方法来释放对象吗?
感谢您的帮助!
将数据构造成对象[][]以放入表中的代码。
private Object[][] getProdutosObjects() {
ProdutoModel pm = new ProdutoModel();
try {
data = pm.getAllProducts();
} catch (DefaultException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(this, e.getMsg(), "", JOptionPane.WARNING_MESSAGE);
}
Object[][] matriz = new Object[data.size()][3];
int i = 0;
for (Object p : data) {
matriz[i][0] = ((Object[])p)[0]; //codigodist
matriz[i][1] = ((Object[])p)[1]; //descricao
matriz[i][2] = ((Object[])p)[2]; //descricaodist
i++;
}
return matriz;
}
创建jtable的代码:
jTable1.setModel(new javax.swing.table.DefaultTableModel(
getProdutosObjects(),
new String [] {
"Código", "Descrição", "Descrição Distribuidor"
}
){
boolean[] canEdit = new boolean [] {
true, false, false
};
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit [columnIndex];
}
});
jTable1.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent event) {
jTable1.scrollRectToVisible(jTable1.getCellRect(
jTable1.getSelectedRow(), 0, true));
}
});
最佳答案
创建弱引用或软引用对象,以便GC在达到一定阈值周期后清除引用。
关于JTable char[]、字符串和对象消耗 Java 堆空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23401318/