我正在編寫一個應用程序,它使用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