Недостаточно памяти при использовании Postgres в Java - PullRequest
2 голосов
/ 17 декабря 2008

Что ж, у нас есть веб-приложение, работающее на JBoss, и у нас возникает ошибка «OutOfMemory» при попытке вставить много строк в несколько таблиц базы данных postgres. Это полная среда для этой ошибки:
* JBoss 4.3.x GA
* Java 1.6.0
* Hibernate 3.0
* postgreSQL-8.3 (драйвер)
О фактической среде работы с кодом:
* Важным моментом является то, что мы анализируем огромное количество XML-документов, каждый из которых загружается отдельно с определенного URL-адреса (1 URL = 1 XML). Мы достигаем этого, имея EJB, который распределяет сгенерированные URL-адреса в очередь, затем пул MDB соединяется с помощью потоков и генерирует документы (обратите внимание, что нам фактически пришлось увеличить объем стековой памяти из-за размера документов XML, и мы застрял с необходимостью получить весь документ в одном потоке), как только документ сгенерирован, он переходит в другую очередь, где слушает другой пул MDB.
Эти MDB анализируют документ, сохраняя информацию в нескольких объектах (не менее 5), которые затем сохраняются в БД (обратите внимание, что управление транзакциями установлено на "BEAN" и начинается и фиксируется во время каждой работы MDB. ). Последовательная обработка URL-адресов невозможна из-за количества обрабатываемых URL-адресов, это может занять около 2 месяцев или около того ... lol

Проблема в том, что ... мы анализируем и храним около 200 URL-адресов или около того и начинаем выводить из памяти ошибку для postgreSQL. Есть идеи ??

Заранее спасибо !!

ТАКЖЕ: Может быть полезно знать, что эта ошибка не появлялась раньше (я проанализировал несколько тысяч этого XML-кода до этого), только генерация документов и анализ некоторых из них в некоторые сущности, по-видимому, не приносили беда. Проблемы начались, когда мы начали разбирать все больше и больше документов на соответствующие им объекты. (Подобно тому, как одна сущность имеет список «функций» [другая сущность анализируется из того же xml])

Ответы [ 2 ]

2 голосов
/ 17 декабря 2008

Звучит так, будто вы храните все бины для всех 200 документов в памяти.

Вместо того, чтобы хранить все данные в оперативной памяти все время, постарайтесь избавиться от них как можно быстрее.

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

Если вы не можете сделать это, используйте профилировщик, чтобы убедиться, что вы не сохранили ссылку на документ после того, как проанализировали его. Обычно вам не нужно хранить весь документ где-либо после его сохранения в БД. Если это проблема, создайте таблицу со ссылками, которая позволяет связывать документы, и просто храните ключи в этой таблице в памяти (а не весь документ).

1 голос
/ 17 декабря 2008

Краткий ответ - требуется дополнительная информация. Я предлагаю использовать такой инструмент, как JProfiler , чтобы понять, где используется память.

На основе вашего описанного дизайна: зачем использовать два пула? Если у вас просто был пул для URL-адресов, то рабочие потоки могли бы извлечь его из этого пула, проанализировать URL-адрес и создать бины сущностей, сохранив их в БД.

Не ясно, зачем вам нужен промежуточный шаг XML, который звучит как вероятный источник высокого потребления памяти.

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