мое написанное на Java приложение потребляет слишком много памяти.
Как работает программа : пользователь выбирает дату из календаря (GUI) и приложение загружает данные в компонент JTable. Каждый раз, когда данные загружаются, создается и устанавливается новая TableModel. Новый JTable не создается, просто модель.
В чем проблема? : выбор каждого нового дня из календаря и загрузка в JTable занимает около 2-3 МБ памяти. При запуске приложение потребляет около 50-60 МБ ОЗУ, после нескольких «щелчков» по календарю (например, 20), приложение использует полный размер кучи (128 МБ) . Приложение вылетает, конечно ...
Что мне делать? : Я почти уверен, что запросы к базе данных в порядке. Я мог бы как-то установить больший размер кучи (я гуглил, но это было бы единственным решением для моего компьютера, пользователи этого не делают) ИЛИ мне как-то нужно удалить старую TableModel с данными БД. Но это не должно быть мусором коллекторская работа? Я могу заставить его (System.gc ()), но это не помогает ...
Спасибо за любой совет!
РЕДАКТИРОВАТЬ: Код для обработки событий календаря (я удалил 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 МБ
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