Ошибка java.lang.OutOfMemory при получении записей из базы данных - PullRequest
0 голосов
/ 19 марта 2010

Когда я пытаюсь получить около 20 000 записей и вернуться в ArrayList, он выдает ошибку пространства кучи Java.

   JdbcTemplate select = new JdbcTemplate(dataSource);
            String SQL_SELECT_XML_IRP_ADDRESS = " SELECT * FROM "+ SCHEMA +".XML_ADDRESS "+
                                                    " WHERE FILE_NAME = ? ";
            Object[] parameters=new Object[] {xmlFileName};
            return (ArrayList<XmlAddressDto> ) select.query(SQL_SELECT_XML_ADDRESS,
                    parameters,new XmAddressMapExt());

Наша база данных - Oracle и используется драйвер oracle thin.
Есть ли решение для этого? Как мне обработать это эффективно?

Ответы [ 4 ]

3 голосов
/ 19 марта 2010

Ответить сложно, не зная деталей вашей системы, но есть несколько вариантов:

  • Увеличение памяти для JVM (см. Много других вопросов по SO)
  • избегать обработки всех записей одновременно;попробуйте захватить подмножество вашего запроса, обработайте его, а затем повторите, вместо того, чтобы разбрасывать все подряд*
1 голос
/ 01 апреля 2010

Основная проблема заключается в том, что у вас, вероятно, недостаточно памяти для хранения в памяти 20 000 копий объекта XmlAddressDto. Пара вариантов:

  1. Добавьте больше памяти (или большую кучу, используйте -Xmx при запуске JVM)
  2. Работа с подмножеством в памяти - либо лениво инициализировать коллекцию (например, кэшировать только последние 200 или около того записей, попадающих через БД для других). Вы могли бы даже обернуть эту коллекцию в интерфейс List, что могло бы выполнить то, что вы пытаетесь сделать, - хотя вы должны быть осторожны с доступом или такими вещами, как перебор его членов
  3. Рисунок, как сделать объект XML меньше - возможно, сохранить двоичное или строковое представление, если DTO - объект полного дерева, и распаковать его, если вам нужно его использовать - особенно в случае, если вы просто собираетесь передать полный XML к другому коду для работы.
1 голос
/ 19 марта 2010

Вам действительно нужно, чтобы все 20000 результатов были сохранены в памяти?

Если вы просто хотите обработать все 20000 результатов, вы должны использовать RowCallbackHandler , выполняющий обработку для каждой строки, и setFetchSize () , чтобы избежать полного выбора памяти.

1 голос
/ 19 марта 2010

Вам нужно хранить все поля всех 20 000 записей одновременно?

Предположительно, вам нужно обработать их и получить что-то из этих данных. Затем создайте свой алгоритм так, чтобы он одновременно считывал N записей (скажем, 100), обрабатывал их и затем переходил к следующей группе.

Возможно, вы также захотите взглянуть на класс Spring SqlQuery, который может помочь вам выполнить вычисления над набором результатов, возвращаемых SQL-запросом.

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