Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Загрузка очень большого числа обьектов для юзера 
V
    Опции темы
Key
Дата 3.7.2008, 17:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 6.12.2007

Репутация: нет
Всего: 1



В базе веб-приложения хранятся логи. Надо сделать чтоб при запросе юзера ему отдавало в поток для закачки сформированый файл с текстом логов. Но проблема в том что их очень много, сотни тысяч! Загрузить их в коллекцию не получается, вылетает аут оф мемори еррор. Пробовал по частях записывать в файл (по пару тысяч), но не помогает, то же самое. Максимум 20 тыс. получается. Подскажите как можно такое сделать.
PM MAIL ICQ   Вверх
man_without_face
Дата 3.7.2008, 17:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 78
Регистрация: 1.4.2008

Репутация: нет
Всего: 1



партиями складировать в архивы можно например.
PM MAIL   Вверх
ivg
Дата 3.7.2008, 19:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Autonomous R&D
**


Профиль
Группа: Участник
Сообщений: 686
Регистрация: 8.2.2006
Где: Екатеринбург

Репутация: 32
Всего: 81



Обрабатывайте на лету, и сразу выдавайте в выходной поток пользователю. Вроде очевидно?
PM MAIL   Вверх
Key
Дата 3.7.2008, 19:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 6.12.2007

Репутация: нет
Всего: 1



Цитата(ivg @ 3.7.2008,  19:04)
Обрабатывайте на лету, и сразу выдавайте в выходной поток пользователю. Вроде очевидно?

Да, но суть в том что надо сперва загрузить кусок данных с базы - записать в файл или поток, загрузить следующий - записать в файл или поток.
Условно :
Код


List<Log> logs = new ArrayList<Log>();

int startIndex;

logs = getDataFromDatabase(startIndex, startIndex+10000);

// запись logs  в поток

startIndex+=10000;

logs = getDataFromDatabase(startIndex, startIndex+10000);

// запись logs  в поток


И так далее. Ну это в цыкле должно быть и т.п.

Проблема в том что память не очищается, хотя сылка logs уже указывает на другой аддрес. Через некоторое время память забивается и вылетает ексепшн. Помогает установка большего размера памяти для сервера (Томкета), но это плохое решение.

PM MAIL ICQ   Вверх
ivg
Дата 3.7.2008, 20:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Autonomous R&D
**


Профиль
Группа: Участник
Сообщений: 686
Регистрация: 8.2.2006
Где: Екатеринбург

Репутация: 32
Всего: 81



1. Почему 10000, а не 1000, 100, 10 ....?
Цитата(Key @  3.7.2008,  22:32 Найти цитируемый пост)
Проблема в том что память не очищается

2. Как узнали? Строчка лога из 5 символов существенно отличается от строки из 500 символов, так? А что если в 5-ой или 10-ой партии которую вы читаете с сервера таких строк большинство? Не это ли является причиной истощения памяти?
Ну а если вы видите что память действительно не очищается, то ищите причину и устраняйте. Покажите код метода getDataFromDatabase()
PM MAIL   Вверх
tux
Дата 3.7.2008, 20:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Летатель
***


Профиль
Группа: Участник Клуба
Сообщений: 1853
Регистрация: 10.2.2005
Где: msk.ru

Репутация: 74
Всего: 132



1. А почему нельзя создать ResultSet с флагом ResultSet.TYPE_SCROLL_INSENSITIVE, скроллить результат и построчно записывать в файл? Память при этом будет использоваться по минимуму. СУБД не позволяет?
2. Если первое не проходит, то, например, MySQL умеет так: "SELECT * FROM tbl LIMIT 5,10", выбирая таким образом строки 6-15.

Первый номер будет работать существенно быстрее.
PM MAIL Skype GTalk Jabber YIM   Вверх
Key
Дата 4.7.2008, 10:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 6.12.2007

Репутация: нет
Всего: 1



Цитата
   А что если в 5-ой или 10-ой партии которую вы читаете с сервера таких строк большинство? Не это ли является причиной истощения памяти?  


Об этом я както не подумал, посмотрю. Просто у меня логи обьекты и не задумался что туда записывается. Возможно гдето они занимают больше памяти.

Цитата
 
1. А почему нельзя создать ResultSet с флагом ResultSet.TYPE_SCROLL_INSENSITIVE, скроллить результат и построчно записывать в файл? Память при этом будет использоваться по минимуму. СУБД не позволяет? 


Просто у меня используется Hibernate/JPA.

В методе выборки записано:

Код

public List<Log> loadFromDatabase(offset, limit) {
Query query = null;
String startQuery = "SELECT logs FROM Logs logs left join logs.user u";
Query query = em.createQuery(startQuery);

query.setFirstResult(offset);
query.setMaxResults(limit);

return query.getResultList();

}


Вроде этого. Думал может JPA выдирает всю базу и выдает только кусок, но судя по логах гибернейта используется команда MySQL LIMIT.

Буду копать дальше, понял что скорее всего чтото упустил.

PM MAIL ICQ   Вверх
ivg
Дата 6.7.2008, 09:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Autonomous R&D
**


Профиль
Группа: Участник
Сообщений: 686
Регистрация: 8.2.2006
Где: Екатеринбург

Репутация: 32
Всего: 81



Цитата из Hibernate FAQ:
Цитата

I am experiencing slow performance or low memory when inserting or querying 10000 objects

In Hibernate 3.0 or earlier you must manage the size of the session cache using clear() or evict(). See also:

http://www.hibernate.org/hib_docs/v3/refer...html/batch.html

In Hibernate 3.1, you can use StatelessSession.

Even better, try to use HQL bulk queries where possible.


Это сообщение отредактировал(а) ivg - 6.7.2008, 09:24
PM MAIL   Вверх
Key
Дата 7.7.2008, 17:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 6.12.2007

Репутация: нет
Всего: 1



Цитата(ivg @ 6.7.2008,  09:06)
Цитата из Hibernate FAQ:
Цитата

I am experiencing slow performance or low memory when inserting or querying 10000 objects

In Hibernate 3.0 or earlier you must manage the size of the session cache using clear() or evict(). See also:

http://www.hibernate.org/hib_docs/v3/refer...html/batch.html

In Hibernate 3.1, you can use StatelessSession.

Even better, try to use HQL bulk queries where possible.

спасибо  smile 
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java EE (J2EE) и Spring | Следующая тема »


 




[ Время генерации скрипта: 0.0666 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.