Переполнение памяти при работе с ResultSet
От: Аноним  
Дата: 01.08.05 10:40
Оценка:
Привет всем !!!!!

Имеется следующий код программы, которая делает выборку информации из таблицы, содержащей несколько миллионов записей


 
import java.sql.*;

   ...
   Connection targetCon; 
   Statement targetStmt;    
   ResultSet targetRs;    

   ...

   targetCon = DriverManager.getConnection (targetURL,dbfInProperties);
   targetStmt = targetCon.createStatement ();
   targetRs = targetStmt.executeQuery("select * from table1");
   while (targetRs.next()) {  
      //обработка записей
   }
   targetRs.close();
   targetStmt.close();
   targetCon.close();
   ...


При чтении в цикле записей (примерно несколько сот тысяч записей) задача "вылетает" с сообщением об ошибке
о нехватке памяти для приложения. Из этой ситуации удается выйти, если увеличить объем выделяемой памяти под приложение (параметр командной строки -Xmx256m). Однако, это не спасает ситуацию в принципе.
Получается, что все прочитанные записи ResultSet хранит у себя в памяти. Эта ошибка происходит со всеми серверами СУБД, используемые в проекте (MSSQL, Informix, DBF). (использование хранимой процедуры в данной ситуации не приемлемо).

Помогите разрешить эту проблемму !!!!!!!!!!!!!
Re: Переполнение памяти при работе с ResultSet
От: Beard-electronic Россия  
Дата: 01.08.05 10:46
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Помогите разрешить эту проблемму !!!!!!!!!!!!!


Читать данные кусками, например от 1 записи до 1000, от 1001 до 2000 и т.д.
Re: Переполнение памяти при работе с ResultSet
От: Lucker Беларусь http://lucker.intervelopers.com/
Дата: 01.08.05 11:08
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Привет всем !!!!!


А>Имеется следующий код программы, которая делает выборку информации из таблицы, содержащей несколько миллионов записей


А>При чтении в цикле записей (примерно несколько сот тысяч записей) задача "вылетает" с сообщением об ошибке

А>о нехватке памяти для приложения. Из этой ситуации удается выйти, если увеличить объем выделяемой памяти под приложение (параметр командной строки -Xmx256m). Однако, это не спасает ситуацию в принципе.
А>Получается, что все прочитанные записи ResultSet хранит у себя в памяти. Эта ошибка происходит со всеми серверами СУБД, используемые в проекте (MSSQL, Informix, DBF). (использование хранимой процедуры в данной ситуации не приемлемо).

А>Помогите разрешить эту проблемму !!!!!!!!!!!!!




попробуй поиграть с setFetchSize у Connection или Statement. может помочь. Вот только щас нашел, что если установить fetchSize в Integer.MIN_VALUE и использовать флаги java.sql.ResultSet.TYPE_FORWARD_ONLY и java.sql.ResultSet.CONCUR_READ_ONLY, то mySQL создает streaming ResultSet, то есть не выбирает все записи из базы, а читает их по мере скроллирования курсора.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[2]: Переполнение памяти при работе с ResultSet
От: Аноним  
Дата: 01.08.05 11:09
Оценка:
Здравствуйте, Beard-electronic, Вы писали:

BE>Читать данные кусками, например от 1 записи до 1000, от 1001 до 2000 и т.д.


вот-вот
1)добавить поле допустим Id=AutoIncrement

2)выборка
"select * from table where Id>"+LastId+" limit 1000"

3)из последней записи получаем Id и записываем в LastId

4)повторить с операции 2
Re[2]: Переполнение памяти при работе с ResultSet
От: dimok@  
Дата: 01.08.05 11:15
Оценка:
Здравствуйте, Lucker, Вы писали:


L>попробуй поиграть с setFetchSize у Connection или Statement. может помочь. Вот только щас нашел, что если установить fetchSize в Integer.MIN_VALUE и использовать флаги java.sql.ResultSet.TYPE_FORWARD_ONLY и java.sql.ResultSet.CONCUR_READ_ONLY, то mySQL создает streaming ResultSet, то есть не выбирает все записи из базы, а читает их по мере скроллирования курсора.


ИМХО можно resultSet.setFetchSize перед первым next.
Re[3]: Переполнение памяти при работе с ResultSet
От: Lucker Беларусь http://lucker.intervelopers.com/
Дата: 01.08.05 11:20
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>вот-вот

А>1)добавить поле допустим Id=AutoIncrement

так а если поля нет и добавить нельзя?
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[3]: Переполнение памяти при работе с ResultSet
От: Lucker Беларусь http://lucker.intervelopers.com/
Дата: 01.08.05 11:25
Оценка:
Здравствуйте, dimok@, Вы писали:

L>>попробуй поиграть с setFetchSize у Connection или Statement. может помочь. Вот только щас нашел, что если установить fetchSize в Integer.MIN_VALUE и использовать флаги java.sql.ResultSet.TYPE_FORWARD_ONLY и java.sql.ResultSet.CONCUR_READ_ONLY, то mySQL создает streaming ResultSet, то есть не выбирает все записи из базы, а читает их по мере скроллирования курсора.


D>ИМХО можно resultSet.setFetchSize перед первым next.

Если в лрайвере реализована полноценная поддержка setFetchSize — то да, можно и у resultSet. Иначе, как, например, в приведенном мной примере с MySQL, это может не сработать, так как запрос на сервер и его обработка может начаться раньше создания самого resultSetа, и дальнейшее его изменение ни к чему не приведет.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[2]: Переполнение памяти при работе с ResultSet
От: Beard-electronic Россия  
Дата: 01.08.05 11:25
Оценка:
Здравствуйте, Lucker, Вы писали:

L>попробуй поиграть с setFetchSize у Connection или Statement. может помочь. Вот только щас нашел, что если установить fetchSize в Integer.MIN_VALUE и использовать флаги java.sql.ResultSet.TYPE_FORWARD_ONLY и java.sql.ResultSet.CONCUR_READ_ONLY, то mySQL создает streaming ResultSet, то есть не выбирает все записи из базы, а читает их по мере скроллирования курсора.


Зачем так хитро? Можно просто установить FetchSize в 100, например.
И еще, наверное, надо в коннекшене указать селект метод — курсор.
Re[3]: Переполнение памяти при работе с ResultSet
От: Lucker Беларусь http://lucker.intervelopers.com/
Дата: 01.08.05 11:27
Оценка:
Здравствуйте, Beard-electronic, Вы писали:

BE>Зачем так хитро? Можно просто установить FetchSize в 100, например.


Потому что в jdbc mysql пока не реализована полная поддержка FetchSize.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[3]: Переполнение памяти при работе с ResultSet
От: Paulpa  
Дата: 01.08.05 11:41
Оценка:
Здравствуйте, Beard-electronic, Вы писали:

BE>Здравствуйте, Lucker, Вы писали:


L>>попробуй поиграть с setFetchSize у Connection или Statement. может помочь. Вот только щас нашел, что если установить fetchSize в Integer.MIN_VALUE и использовать флаги java.sql.ResultSet.TYPE_FORWARD_ONLY и java.sql.ResultSet.CONCUR_READ_ONLY, то mySQL создает streaming ResultSet, то есть не выбирает все записи из базы, а читает их по мере скроллирования курсора.


BE>Зачем так хитро? Можно просто установить FetchSize в 100, например.

BE>И еще, наверное, надо в коннекшене указать селект метод — курсор.


Установлено. Результат тот же
Re: Переполнение памяти при работе с ResultSet
От: fefelov Россия  
Дата: 01.08.05 11:44
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Помогите разрешить эту проблемму !!!!!!!!!!!!!


CachedRowSet
пункт 10.0 Paging Data
Re[2]: Переполнение памяти при работе с ResultSet
От: Lucker Беларусь http://lucker.intervelopers.com/
Дата: 01.08.05 11:55
Оценка:
Здравствуйте, fefelov, Вы писали:

F>CachedRowSet

F>пункт 10.0 Paging Data

Интересно, как много ведеров поддерживают это?
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[2]: Переполнение памяти при работе с ResultSet
От: Paulpa  
Дата: 01.08.05 12:06
Оценка:
Здравствуйте, Lucker, Вы писали:

L>Здравствуйте, <Аноним>, Вы писали:


А>>Привет всем !!!!!


А>>Имеется следующий код программы, которая делает выборку информации из таблицы, содержащей несколько миллионов записей


А>>При чтении в цикле записей (примерно несколько сот тысяч записей) задача "вылетает" с сообщением об ошибке

А>>о нехватке памяти для приложения. Из этой ситуации удается выйти, если увеличить объем выделяемой памяти под приложение (параметр командной строки -Xmx256m). Однако, это не спасает ситуацию в принципе.
А>>Получается, что все прочитанные записи ResultSet хранит у себя в памяти. Эта ошибка происходит со всеми серверами СУБД, используемые в проекте (MSSQL, Informix, DBF). (использование хранимой процедуры в данной ситуации не приемлемо).

А>>Помогите разрешить эту проблемму !!!!!!!!!!!!!




L>попробуй поиграть с setFetchSize у Connection или Statement. может помочь. Вот только щас нашел, что если установить fetchSize в Integer.MIN_VALUE и использовать флаги java.sql.ResultSet.TYPE_FORWARD_ONLY и java.sql.ResultSet.CONCUR_READ_ONLY, то mySQL создает streaming ResultSet, то есть не выбирает все записи из базы, а читает их по мере скроллирования курсора.


------

Попробовал. Результат тот же
Re[2]: Переполнение памяти при работе с ResultSet
От: Paulpa  
Дата: 01.08.05 12:51
Оценка:
Здравствуйте, fefelov, Вы писали:

F>Здравствуйте, Аноним, Вы писали:


А>>Помогите разрешить эту проблемму !!!!!!!!!!!!!


F>CachedRowSet

F>пункт 10.0 Paging Data

-------

Не помогло. Памяти отжирает еще больше.
Re[2]: Переполнение памяти при работе с ResultSet
От: Mycopka Россия http://mhehue.info
Дата: 01.08.05 12:59
Оценка:
Здравствуйте, fefelov, Вы писали:

F>CachedRowSet

F>пункт 10.0 Paging Data

Вещь хорошая, но не по той части --- по сравнению с обычной версией ест больше памяти, но работает быстрее ( при наличае той самой памяти ).
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
---
With best regards и все такое :)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.