Russian Qt Forum
Ноябрь 23, 2024, 12:17 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3 ... 7   Вниз
  Печать  
Автор Тема: QSqlQuery+QThread = bad_alloc  (Прочитано 43537 раз)
cdsmika
Гость
« : Май 16, 2014, 11:39 »

Привет!
Выбираю из MSSQL через QODBC данных на 248 Мб (как показывает Management Studio) в память для обработки и пересыла по фтп.
Все замечательно, пока код в основном потоке. Стоит перенести в отдельный поток - валится bad_alloc.
Собственно интересно почему?

Написал тест:
Код:
void Thread::run()
{
    QSqlDatabase udb;
    udb = QSqlDatabase::addDatabase( "QODBC", "conn" );
    udb.setDatabaseName( "Driver={SQL Server Native Client 10.0};Server=(local);Database=ks;UID=sa;PWD=1;" );
    udb.open();

    QStringList l;

    QSqlQuery query( udb );
    query.setForwardOnly(true);
    query.prepare("EXEC dbo.get_initial_data '56FEB471-37A7-494E-AF87-8FC03174C74F'");
    query.exec();

    while (query.next())
    {
        l.append(query.value(1).toString());
    }
}
« Последнее редактирование: Май 16, 2014, 12:14 от cdsmika » Записан
cdsmika
Гость
« Ответ #1 : Май 16, 2014, 11:52 »

Даже вот так уже bad_alloc:
Код:
void Thread::run()
{
    QString l;

    while (l.length() < 200000000)
    {
        l.append("1111111111111");
    }
}
Записан
cdsmika
Гость
« Ответ #2 : Май 16, 2014, 12:01 »

Win 7 x64 + Qt 4.8.4
Записан
Hellraiser
Бывалый
*****
Offline Offline

Сообщений: 451


Просмотр профиля
« Ответ #3 : Май 16, 2014, 12:36 »

А ~400 Мб не многовато для стековой переменной?
Записан
OKTA
Гость
« Ответ #4 : Май 16, 2014, 12:40 »

Тут больше интересно, почему валится, а не то, что многовато  Улыбающийся
Кода бы увидеть побольше!
Записан
cdsmika
Гость
« Ответ #5 : Май 16, 2014, 12:49 »

А ~400 Мб не многовато для стековой переменной?
как узнать многовато или нет?
Записан
cdsmika
Гость
« Ответ #6 : Май 16, 2014, 12:51 »

Тут больше интересно, почему валится, а не то, что многовато  Улыбающийся
Кода бы увидеть побольше!
а это собственно весь код)
Записан
Bepec
Гость
« Ответ #7 : Май 16, 2014, 12:54 »

Ничего не вылетает. Спокойно завершается поток, потолок потребления памяти примерно 550 мб. Видимо у вас где-то что-то ещё.
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #8 : Май 16, 2014, 12:57 »

А ~400 Мб не многовато для стековой переменной?
как узнать многовато или нет?
Это не имеет отношения к делу..

QString - это фактически контейнер, который при расширении (из-за ваших постоянных append ов) пытается аллоцировать себе новый блок памяти.. Видимо вы уже до того её дефрагментировали, что такого цельного куска просто нет, вот он кидает bad_alloc.  
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
cdsmika
Гость
« Ответ #9 : Май 16, 2014, 13:02 »

А ~400 Мб не многовато для стековой переменной?
как узнать многовато или нет?
Это не имеет отношения к делу..

QString - это фактически контейнер, который при расширении (из-за ваших постоянных append ов) пытается аллоцировать себе новый блок памяти.. Видимо вы уже до того её дефрагментировали, что такого цельного куска просто нет, вот он кидает bad_alloc.  

Я пробовал аллоцировать и цельный кусок ) Результат тот же. Как понять тогда влезет кусок или нет?
Записан
OKTA
Гость
« Ответ #10 : Май 16, 2014, 13:06 »

Определять влезет/не влезет -совсем плохой метод. Проще ловить исключение и реорганизовать работу программы, чтобы не приходилось таскать в памяти такие огромные куски данных.
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #11 : Май 16, 2014, 13:08 »

Цитировать
Как понять тогда влезет кусок или нет?
Ну как-как.. Если исключение не кинет, значит влезет, а ели кинет, то значит нет)

Ловите исключения и решайте сами, как на это реагировать..
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
cdsmika
Гость
« Ответ #12 : Май 16, 2014, 13:41 »

Определять влезет/не влезет -совсем плохой метод. Проще ловить исключение и реорганизовать работу программы, чтобы не приходилось таскать в памяти такие огромные куски данных.
По нынешним меркам разве огромные? Да для среднего сервака это ж пшик)
Записан
OKTA
Гость
« Ответ #13 : Май 16, 2014, 14:11 »

Для сервака, сколько бы "планок" в нем не стояло, требования к производительности и маленькому потреблению памяти еще выше и жестче.
И дело не в нынешних мерках, а в хороших программах. Если руководствоваться при программировании мнением, что "ну на всех нынешних компах памяти больше гига, так что можно смело отхватить пару сотен метров", то это приведет к тому в итоге, что программа будет работать криво, а зачастую вообще не будет работать, если по каким-то причинам памяти ей не хватит свободной. Надо работать с тем, что дает система, а не с тем, что "да все компы мощные уже, везде уверен будет работать"  Подмигивающий
Записан
Bepec
Гость
« Ответ #14 : Май 16, 2014, 14:15 »

Ну тут тоже не совсем верно, OKTA. Опять таки по задаче смотреть и направлению.
Какие то программы должны работать только на больших серверах Улыбающийся

Ну и нижнюю планку тоже надо держать. Ведь как не удумай, упихнуть средней сложности программу для работы с данными в 16-20 мб вряд ли получится Улыбающийся
Записан
Страниц: [1] 2 3 ... 7   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.118 секунд. Запросов: 23.