Как освободить память после извлечения данных через jdbc - PullRequest
2 голосов
/ 11 января 2012

Я использую Spring JDBC на WebLogic. И я установил размер выборки до 500 для получения данных из БД быстрее. Но это вызывает проблемы с памятью. Вот пример:

http://webmoli.com/2009/02/01/jdbc-performance-tuning-with-optimal-fetch-size/

Мой вопрос, как освободить эту память? Запуск GC не работает, я думаю, что он не работает, потому что соединение активно в пуле соединений.

Код:

public List<Msisdn> getNewMsisdnsForBulkSmsId(String bulkSmsId,String scheduleId,final int msisdnCount) throws SQLException {
            JdbcTemplate jdbcTemplate = getJdbcTemplate();
            jdbcTemplate.setFetchSize(500);
            jdbcTemplate.setMaxRows(msisdnCount);
            jdbcTemplate.query("select BULKSMS_ID, ? as , STATUSSELECTDATE, DELIVERYTIME, ID, MESSAGE from ada_msisdn partition (ID_"+bulkSmsId+") where bulksms_id = ? and status = 0 and ERRORCODE = 0 and  SCHEDULEID is null for update skip locked", new Object[]{scheduleId,bulkSmsId}, MsisdnRowMapper.INSTANCE);

  //Also i tried to close connection and run gc, this does not free the memory too.
            //jdbcTemplate.getDataSource().getConnection().close();
            //System.gc();

            return null;
}

когда я устанавливаю размер выборки равным 10, размер кучи составляет 12 МБ если установить размер выборки 500, размер кучи составит 206 МБ

Thanx

1 Ответ

1 голос
/ 11 января 2012

Обновления для добавленного примера кода и т.д .:

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

Теперь, когда я вижу, что вы сохраняете все отображенных результатов в List, я бы сказал, что проблема, возникающая при полученииразмер, вероятно, будет вторичной проблемой.Объединенное пространство памяти, необходимое для List<Msisdn> и отдельной группы извлеченных строк ResultSet, выталкивает вас за пределы доступной памяти.

Какое значение msisdnCount?Если оно больше 500, то вы, вероятно, используете больше памяти в list, чем в 500 записях ResultSet.Если оно меньше 500, то я ожидаю, что проблема с памятью также возникает, когда вы устанавливаете размер выборки на msisdnCount, и ошибка исчезает при некотором значении между min(msisdnCount, 500) и 10.

Загрузкавсе результаты в виде списка и последующей их обработки - это шаблон, который очень часто приводит к исчерпанию памяти.Распространенным решением является использование streaming .Если вы можете обработать каждую строку по мере поступления и не сохранить все результаты карт в вашем list, тогда вы можете избежать проблем с памятью.

Я не вижу никакихподдержка потоковой передачи в основном пакете Spring JDBC, но я обновлю, если найду его.

-

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

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

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

edit: Вы можете также захотеть установить поведение курсора, чтобы дать вашему драйверу JDBC больше информации, чтобы узнатьчто он может выбросить.Вы можете подготовить свои заявления с помощью ResultSet.TYPE_FORWARD_ONLY, например, ResultSet.CONCUR_READ_ONLY.http://docs.oracle.com/javase/6/docs/api/index.html?java/sql/ResultSet.html

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