* РЕДАКТИРОВАТЬ: Я сам нашел ответ на утечку памяти, и отправил его вместе с другими.Если кто-то может ответить, почему я должен применить исправление вообще (см. Вопрос в моем ответе), я с радостью приму ответ :-) *
Я написал простую утилиту, которая периодически читает журналфайлы и сохраняет записи в базе данных.Не так много кода и, похоже, работает нормально.Но после запуска его на большом количестве журналов сегодня я обнаружил, что он не готов к работе ... После того, как первое задание было закончено, просматривая все журналы, следующие 15 заданий будут запускаться до тех пор, пока не будет установлено больше соединений.и следующая работа потерпит неудачу с SqlException.В течение следующих пяти часов приложение выводило исключения незаметно до тех пор, пока не закончилась память.
Задание было настроено с использованием следующего триггера cron «* * / 2 * * *?», Что означает «запускать каждыйпару минут".Странно то, что после того, как первая работа была закончена (на это ушло около часа), оставшиеся рабочие места быстро сработали, одна за другой.Это было неожиданно, так как я думал, что между каждой работой должно быть две минуты.
Теперь мне интересно, что может быть не так.Я предполагаю, что причина в том, как я использую Hibernate и / или Quartz.Может быть, я не выпускаю сеанс так, как должен, или неправильно понял, как Quartz планирует задания? Или, может быть, я должен внедрить фабрику Hibernate в работу, а не создавать ее в каждой работе?getCurrentSession () против openSession ()?Без понятия.Я до сих пор не понимаю, почему это должно иметь какой-либо эффект, так как задания должны освободить все ресурсы при выходе.Во всяком случае, большая часть соответствующего кода будет показана ниже.
Независимо от того, решена ли проблема с подключением, код страдает от некоторой утечки памяти.Как будто каждая выполненная работа каким-то образом хранится в куче.Выполнив
java -Xmx17M -DcronTriggerExpression="*/1 * * * * ?" -jar myjar.jar
,
, я могу заставить проблему появиться, запустив программу с минимальным объемом памяти.В этом случае требуется всего четыре последовательных запуска, прежде чем я получу ошибку OutOfMemoryError при создании фабрики сеансов для спящего режима.
public class ExportJob implements Job {
LogImporter importer;
public ExportJob() { //needed for Quartz
setUpHibernate();
importer = new LogImporter(); //injected, but this saves space on SO :)
}
public void execute(JobExecutionContext context) throws JobExecutionException {
/* even if this body is empty, I get a OutOfMemoryError */
}
private SessionFactory setUpHibernate() {
logger.debug("Setting up hibernate");
this.sessionFactory = new Configuration().configure().buildSessionFactory();
return this.sessionFactory;
}
private Session getSession() {
return sessionFactory.openSession();
}
}