Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > Загрузка очень большого числа обьектов для юзера


Автор: Key 3.7.2008, 17:16
В базе веб-приложения хранятся логи. Надо сделать чтоб при запросе юзера ему отдавало в поток для закачки сформированый файл с текстом логов. Но проблема в том что их очень много, сотни тысяч! Загрузить их в коллекцию не получается, вылетает аут оф мемори еррор. Пробовал по частях записывать в файл (по пару тысяч), но не помогает, то же самое. Максимум 20 тыс. получается. Подскажите как можно такое сделать.

Автор: man_without_face 3.7.2008, 17:19
партиями складировать в архивы можно например.

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

Автор: Key 3.7.2008, 19:32
Цитата(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 уже указывает на другой аддрес. Через некоторое время память забивается и вылетает ексепшн. Помогает установка большего размера памяти для сервера (Томкета), но это плохое решение.

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

2. Как узнали? Строчка лога из 5 символов существенно отличается от строки из 500 символов, так? А что если в 5-ой или 10-ой партии которую вы читаете с сервера таких строк большинство? Не это ли является причиной истощения памяти?
Ну а если вы видите что память действительно не очищается, то ищите причину и устраняйте. Покажите код метода getDataFromDatabase()

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

Первый номер будет работать существенно быстрее.

Автор: Key 4.7.2008, 10:20
Цитата
   А что если в 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.

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

Автор: ivg 6.7.2008, 09:06
Цитата из http://www.hibernate.org/117.html#A34:
Цитата

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/reference/en/html/batch.html

In Hibernate 3.1, you can use StatelessSession.

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

Автор: Key 7.7.2008, 17:39
Цитата(ivg @ 6.7.2008,  09:06)
Цитата из http://www.hibernate.org/117.html#A34:
Цитата

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/reference/en/html/batch.html

In Hibernate 3.1, you can use StatelessSession.

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

спасибо  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)