мое написанное Java приложение потребляет слишком много памяти.
Как работает программа.. Пользователь выбирает дату из календаря (GUI) и приложение загружает данные в компонент JTable. Каждый раз данные загружаются, создается и настраивается новый TableModel. Никакой новый JTable не создается, просто модель.
В чем проблема?: каждый новый день от календаря и загрузка до JTable потребляет около 2-3 МБ памяти. При запуске приложение потребляет около 50-60 МБ оперативной памяти, после нескольких "кликов" по календарю (например, 20) приложение потребляет полный размер кучи (128 МБ). Сбой приложений, конечно...
Что мне делать?. Я уверен, что запросы к базе данных в порядке. Я мог бы как-то установить больший размер кучи (я googled, но это будет только решение для моего компьютера, пользователи этого не сделают) ИЛИ мне нужно как-то удалить старый TableModel с данными БД. Но разве это не должно быть сборщиком мусора? Я могу заставить его (System.gc()), но это не помогает...
Спасибо за любой совет!
EDIT: Код для обработки событий календаря (я удалил Javadoc, это на моем родном языке)
package timesheet.handlers;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import org.jdesktop.swingx.JXMonthView;
import org.jdesktop.swingx.event.DateSelectionEvent;
import org.jdesktop.swingx.event.DateSelectionListener;
import timesheet.database.WorkerOperations;
import timesheet.frames.WorkerFrame;
import timesheet.logictrier.*;
public class WorkerMonthViewHandler {
private JXMonthView monthView;
private WorkerFrame workerFrame;
private WorkerOperations wops;
private Date[] week = new Date[5];
private WorkerTasksTableHandler wtth;
public WorkerMonthViewHandler(WorkerFrame workerFrame) {
this.workerFrame = workerFrame;
this.monthView = workerFrame.getWorkerMonthView();
wops = workerFrame.getWorkerOperations(); // for DB usage
}
public void initMonthView() {
List<Task> tasks = wops.getWorkerTasks(workerFrame.getWorker()); // db select
for (Task task : tasks) {
if (!monthView.getSelection().contains(task.getPlannedStart())) {
monthView.addFlaggedDates(task.getPlannedStart());
monthView.addFlaggedDates(task.gePlannedEnd()); // not really important
}
}
monthView.setSelectionDate(new Date());
monthView.getSelectionModel().addDateSelectionListener(new DateSelectionListener() {
public void valueChanged(DateSelectionEvent dse) {
Date d = monthView.getSelectionDate();
for (int i=0; i<week.length; i++) {
if (d.equals(week[i])) {
return;
}
}
Calendar cal = new GregorianCalendar();
cal.setTime(d);
long dayMs = 24 * 60 * 60 * 1000;
switch (cal.get(Calendar.DAY_OF_WEEK)) {
case(Calendar.MONDAY) : {
week[0] = new Date(cal.getTimeInMillis());
week[1] = new Date(cal.getTimeInMillis()+dayMs);
week[2] = new Date(cal.getTimeInMillis()+2*dayMs);
week[3] = new Date(cal.getTimeInMillis()+3*dayMs);
week[4] = new Date(cal.getTimeInMillis()+4*dayMs);
} break;
case (Calendar.TUESDAY) : {
week[0] = new Date(cal.getTimeInMillis()-dayMs);
week[1] = new Date(cal.getTimeInMillis());
week[2] = new Date(cal.getTimeInMillis()+1*dayMs);
week[3] = new Date(cal.getTimeInMillis()+2*dayMs);
week[4] = new Date(cal.getTimeInMillis()+3*dayMs);
} break;
case (Calendar.WEDNESDAY) : {
week[0] = new Date(cal.getTimeInMillis()-2*dayMs);
week[1] = new Date(cal.getTimeInMillis()-dayMs);
week[2] = new Date(cal.getTimeInMillis());
week[3] = new Date(cal.getTimeInMillis()+1*dayMs);
week[4] = new Date(cal.getTimeInMillis()+2*dayMs);
} break;
case (Calendar.THURSDAY) : {
week[0] = new Date(cal.getTimeInMillis()-3*dayMs);
week[1] = new Date(cal.getTimeInMillis()-2*dayMs);
week[2] = new Date(cal.getTimeInMillis()-1*dayMs);
week[3] = new Date(cal.getTimeInMillis());
week[4] = new Date(cal.getTimeInMillis()+1*dayMs);
} break;
case (Calendar.FRIDAY) : {
week[0] = new Date(cal.getTimeInMillis()-4*dayMs);
week[1] = new Date(cal.getTimeInMillis()-3*dayMs);
week[2] = new Date(cal.getTimeInMillis()-2*dayMs);
week[3] = new Date(cal.getTimeInMillis()-dayMs);
week[4] = new Date(cal.getTimeInMillis());
} break;
case (Calendar.SATURDAY) : {
week[0] = new Date(cal.getTimeInMillis()-5*dayMs);
week[1] = new Date(cal.getTimeInMillis()-4*dayMs);
week[2] = new Date(cal.getTimeInMillis()-3*dayMs);
week[3] = new Date(cal.getTimeInMillis()-2*dayMs);
week[4] = new Date(cal.getTimeInMillis()-dayMs);
} break;
case (Calendar.SUNDAY) : {
week[0] = new Date(cal.getTimeInMillis()-6*dayMs);
week[1] = new Date(cal.getTimeInMillis()-5*dayMs);
week[2] = new Date(cal.getTimeInMillis()-4*dayMs);
week[3] = new Date(cal.getTimeInMillis()-3*dayMs);
week[4] = new Date(cal.getTimeInMillis()-2*dayMs);
} break;
}
wtth = new WorkerTasksTableHandler(workerFrame,week);
wtth.createTable(); // sets model on JTable
}
});
}
public void reportTask() {
wtth.reportTasks(); // simple DB insert
}
}
Использование профилировщика NetBeans:Дата съемки: вс 28 фев 14:25:16 CET 2010 Файл: C:...\private\profiler\java_pid4708.hprof Размер файла: 72,2 MB
Total bytes: 62 323 264
Total classes: 3 304
Total instances: 1 344 586
Classloaders: 18
GC roots: 2 860
Number of objects pending for finalization: 0