утечки памяти стойкости Java - PullRequest
1 голос
/ 14 апреля 2011

У меня есть 1M строк в таблице MySQL, и я api персистентности Java, когда я выполняю следующий код, то я получаю ошибку кучи Java:

int counter = 0;
while (counter < 1000000) {
   java.util.Collection<MyEntityClass> data = myQuery.setFirstResult(counter)
       .setMaxResults(1000).getResultList();
   for(MyEntityClass obj : data){
       System.out.println(obj);
   }
   counter += 1000;
}

Ответы [ 4 ]

7 голосов
/ 14 апреля 2011

Интересно, действительно ли JTable висит на всех этих старых ссылках, когда вы нажимаете "далее"Я не верю, что это проблема постоянства.Какую бы структуру данных вы не поддерживали в JTable, я бы позаботился о том, чтобы очистить ее перед добавлением следующей партии записей.Таким образом, старые значения могут быть GC'd.

Ваш JTable не должен иметь ResultSet.Было бы лучше иметь уровень постоянства, который бы скрывал такие детали от клиентов.Сделайте запрос для пакета значений (, а не всего набора данных), загрузите его из ResultSet в структуру данных и закройте ResultSet и Statement в блоке finally.Вам необходимо закрыть эти ресурсы в области метода, в котором они были созданы, или вы хотите создать проблему.

2 голосов
/ 14 апреля 2011

Проблема почти наверняка состоит в том, что ваш объект resultSet кэширует весь набор результатов, который потребляет много памяти для такого большого запроса.

Вместо того, чтобы сбрасывать индекс для набора результатов, как вы это делаете в настоящее время - который не очищает кэшированный результат, я бы посоветовал вам написать запрос, который извлекает соответствующие строки для данной страницы, и выполнять его каждый раз, когда страница изменения. Откатывайте старый набор результатов каждый раз, чтобы убедиться, что вы ничего не кэшируете.

В зависимости от базы данных, которую вы используете, вы можете использовать псевдостолбец rownum (Oracle), функцию row_number () (DB2, MSSQL) или синтаксис limit x offset y (MySql).

1 голос
/ 14 апреля 2011
  • Является ли это приложением Java EE или Java SE?
  • Как вы управляете вашим менеджером сущностей?

Менеджер сущностей обычно связан с контекстом.Во время транзакции каждая восстанавливаемая сущность будет помещена в нее, и это будет кеш для всех сущностей. Когда транзакция фиксируется, JPA будет искать изменения в контексте и фиксировать изменения в базе данных.

Это означает, что если вы восстановите 1 миллион строк, у вас будет 1 миллион сущностей в вашем контексте, и они не будут собираться мусором, пока вы не закроете свой менеджер сущностей.

Поскольку вы ссылаетесь на JTable IМожно только предположить, что это приложение JSE.В этом типе приложения вы полностью контролируете контекст.В этом типе приложений существует взаимно-однозначная связь между контекстом и менеджером сущностей (что не всегда имеет место в среде Java EE).

Это означает, что вы можете либо создать менеджер сущностей длязапрос (т. е. транзакция или беседа) или менеджер сущностей на весь срок службы приложения.

Если вы используете второй подход, ваш контекст никогда не собирается сборщиком мусора, и чем больше объектов вы читаете из базы данных,оно становится больше, пока вы в конечном итоге не достигнете проблемы с памятью, подобной той, которую вы описываете.

Я не говорю, что это является причиной вашей проблемы, но это, безусловно, может быть хорошим руководством для поиска основной причины,тебе не кажется?

0 голосов
/ 14 апреля 2011

Похоже, ваш результирующий набор не подлежит GC в его конкретном случае.Проверьте ваш код и посмотрите, куда действительно идет ссылка на этот набор результатов, чтобы произошла утечка памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...