![]() |
|
Модераторы: LSD, AntonSaburov |
![]()
|
|
| Alexander06 |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 90 Регистрация: 28.7.2006 Репутация: нет Всего: нет |
Здравствуйте.
Я пишу приложение на Java, работающее с базой данных H2. Сайт СУБД Работа ведется в режиме embedded. Осуществляю загрузку данных из текстового файла в БД. При добавлении записи каждый раз проверяю наличие аналогичной, думаю по-этому, с ростом таблицы, размер выделенной памяти растет. Но после завершения функции и даже закрытия соединения с базой, выделенная память не освобождается. Надо заметить, что иногда использую конструкции вида:
, где rs - объявлена как public ResultSet rs; в классе, работающим с БД. То есть при вызове функции сохраняю предыдущий ResultSet с тем, чтобы потом его вернуть обратно. Насколько я понимаю, полученный в запросе ResultSet должен в последствии быть собран сборщиком мусора. Пробовал принудительно вызывать сборщик после закрытия БД - не помогает. Подскажите, как отследить утечку памяти? Использую IDE NetBeans 6.5, там есть утилита Profiler. В результате работы приложение вызывает превышение максимального размера кучи с результатами выделения памяти: org.h2.result.SimpleRowValue - 23% org.h2.result.Row - 20% java.lang.Object[] - 11% char[] - 10% org.h2.Value.ValueString - 9% org.h2.Value.ValueInt - 9% org.h2.Value.Value[] - 9% org.h2.Result.Row - 9% такое впечатление, что результаты выполнения запросов не удаляются из памяти, а остаются в ней. Если что-то осталось не ясным, спрашивайте, постараюсь уточнить. Заранее спасибо. |
|||
|
||||
| powerOn |
|
|||
![]() software saboteur ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 4367 Регистрация: 7.10.2005 Репутация: 47 Всего: 159 |
может там кэш такой суровый?
|
|||
|
||||
| Alexander06 |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 90 Регистрация: 28.7.2006 Репутация: нет Всего: нет |
Возможно. Я попробовал уменьшить его - занимаемая память сократилась.
Работать уже можно, с сообщениями о превышении допустимого размера не вылетает, хотя память продолжает засоряться. Получается, что в итоге прийду к тем же результатам, только позже. Но ваш совет полезен, спасибо. Может быть есть какие-то правила, чего стоит избегать для своевременного освобождения памяти? |
|||
|
||||
| COVD |
|
||||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 17 Всего: 43 |
Это, мягко говоря, сомнительная затея.
Все что вам нужно, это извлечь из ResultSet'a интересующие вас данные. Обычно резалтсет обьявляют локально, т.е. ссылка на него существует только внутри метода во время извлечения данных. Как-то так
При закрытии соединения автоматически будет освобождена и ссылка соединения на резалтсет. При новом запросе старый резалтсет также автоматически будет освобожден соединением. Таким образом, если не делать своих постоянных ссылок на резалтсет (а вы сделали и необходимость этого неочевидна), то и проблем быть не должно. Это сообщение отредактировал(а) COVD - 24.11.2008, 17:25 |
||||||
|
|||||||
| Alexander06 |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 90 Регистрация: 28.7.2006 Репутация: нет Всего: нет |
Я выделил отдельный класс для выполнения запросов к БД.
В нем создал поле ResultSet rs с тем, чтобы использовать в конструкциях вида
в методах этого класса. Дело в том, что некоторые функции требуют запросить данные из таблицы, а потом для каждой из них выполнить несколько запросов. Поэтому я специально сохраняю старый ResultSet, чтобы не терять результаты внешнего запроса при выполнении внутренних. Я решил, что копировать куда-то результаты из ResultSet, это лишняя работа. Попробую последовать вашему совету. Спасибо. |
|||
|
||||
| COVD |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 17 Всего: 43 |
Очевидно, для "внешних" и "внутренних" запросов вы используете разные соединения, т.е. вы держите открытыми несколько соединений к БД. Возможно, последовательное извлечение данных через одно соединение проще программировать. |
|||
|
||||
| Alexander06 |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 90 Регистрация: 28.7.2006 Репутация: нет Всего: нет |
Соединение использовал одно, устанавливаемое в начале работы программы.
Правда каждый раз выполнял createStatement() перед выполнением запроса, это я убрал, работает. Сейчас программа постепенно выбирает определенную квоту памяти и дальше практически не растет. Наверное это кэш БД. Может где-то и есть утечки, но они не очевидны. Всем спасибо |
|||
|
||||
![]()
|
| Правила форума "Java" | |
|
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Java: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |