我正在编写一个应用程序,它使用JTable来显示日志文件的行。我解析了数据,但是当我尝试将行添加到我的AbstractTableModel时,收到“超出gc开销限制”或“java.lang.OutOfMemoryError:Java堆空间”错误。有没有配置垃圾收集器或更改我的AbstractTableModel以允许我加载所需的行?如何装载2百万行的JTable
package gui;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import javax.swing.table.AbstractTableModel;
import saxxmlparse.logEvent;
/**
*
* @author David.Crosser
*/
public class MyTableModel extends AbstractTableModel {
private String[] columnNames = new String[]{"Type", "Time", "TID", "LID", "User", "Message", "Query", "Protocol", "Port", "IP", "Error"};
private List<logEvent> data;
public MyTableModel() {
data = new ArrayList<>(25);
}
@Override
public Class<?> getColumnClass(int columnIndex) {
if (columnIndex == 1) {
//return Date.class;
return String.class;
} else {
return String.class;
}
}
@Override
public String getColumnName(int col) {
return columnNames[col];
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public int getRowCount() {
return data.size();
}
@Override
public Object getValueAt(int row, int col) {
logEvent value = data.get(row);
Object retObj=null;
switch (col) {
case 0:
retObj = value.getType();
break;
case 1:
retObj = value.getTime();
break;
case 2:
retObj = value.getTid();
break;
case 3:
retObj = value.getLid();
break;
case 4:
retObj = value.getUser();
break;
case 5:
retObj = value.getMsg();
break;
case 6:
retObj = value.getQuery();
break;
case 7:
retObj = value.getProtocol();
break;
case 8:
retObj = value.getPort();
break;
case 9:
retObj = value.getIp();
break;
case 10:
retObj = "N";
break;
}
return retObj;
}
public void addRow(logEvent value) {
int rowCount = getRowCount();
data.add(value);
fireTableRowsInserted(rowCount, rowCount);
}
public void addRows(logEvent... value) {
addRows(Arrays.asList(value));
}
public void addRows(List<logEvent> rows) {
int rowCount = getRowCount();
data.addAll(rows);
fireTableRowsInserted(rowCount, getRowCount() - 1);
}
}
package gui;
import java.sql.ResultSet;
import java.util.List;
import javax.swing.SwingWorker;
import saxxmlparse.logEvent;
/**
*
* @author David.Crosser
*/
public class TableSwingWorker extends SwingWorker<MyTableModel, logEvent> {
private final MyTableModel tableModel;
String query;
dataBase.Database db;
int totalRows=0;
public TableSwingWorker(dataBase.Database db, MyTableModel tableModel, String query) {
this.tableModel = tableModel;
this.query = query;
this.db = db;
}
@Override
protected MyTableModel doInBackground() throws Exception {
// This is a deliberate pause to allow the UI time to render
Thread.sleep(2000);
ResultSet rs = db.queryTable(query);
System.out.println("Start polulating");
while (rs.next()) {
logEvent data = new logEvent();
for (int i = 0; i <= tableModel.getColumnCount(); i++) {
switch (i) {
case 0:
data.setType((String)rs.getObject(i+1));
break;
case 1:
data.setTime((String)rs.getObject(i+1));
break;
case 2:
data.setTid((String)rs.getObject(i+1));
break;
case 3:
data.setLid((String)rs.getObject(i+1));
break;
case 4:
data.setUser((String)rs.getObject(i+1));
break;
case 5:
data.setMsg((String)rs.getObject(i+1));
break;
case 6:
data.setQuery((String)rs.getObject(i+1));
break;
case 7:
data.setProtocol((String)rs.getObject(i+1));
break;
case 8:
data.setPort((String)rs.getObject(i+1));
break;
case 9:
data.setIp((String)rs.getObject(i+1));
break;
case 10:
data.setError((String)rs.getObject(i+1));
break;
}
}
publish(data);
Thread.yield();
}
return tableModel;
}
@Override
protected void process(List<logEvent> chunks) {
totalRows += chunks.size();
System.out.println("Adding " + chunks.size() + " rows --- Total rows:" + totalRows);
tableModel.addRows(chunks);
}
}
加载几次即可查看。或者配置JVM以访问更多内存。请参阅http://stackoverflow.com/questions/6452765/how-to-increase-heap-size-of-jvm – bradimus
为什么我以前的评论被删除?像“+1谢谢”这样的评论是无关紧要的,关于评论优点的元讨论(这应该是元数据中的Q),但这不是我所做的。我提供了一个有用的通知,这是一个常见问题。因此,评论的内容涉及手头的问题类型及其在计算机科学中的地位;误解这一点的人可以从这样的评论中受益。 2人可能从中受益。我已阅读SO的适当内容。如果你不同意足以删除的内容,你应该启发我们的理由。 – Aaron
另请参阅此相关的[示例](http://stackoverflow.com/a/25526869/230513)。 – trashgod