![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
VisualCraft |
|
|||
Новичок Профиль Группа: Участник Сообщений: 44 Регистрация: 24.11.2003 Репутация: нет Всего: нет |
//Подготовка
Query1->SQL->Text="INSERT INTO table1(Field1,Field2) VALUES ("+v1+","+v2+")"; //Проверено, именно этот кусок кода регулярно кушает память примерно по 100-200 байт try{Query1->ExecSQL();} catch ( ... ){ //Попытка дублирования первичного ключа try{ if(Query1->Active) Query1->Close(); Query1->SQL->Text="SELECT * FROM table1 WHERE Field1="+v1; Query1->Open(); if(Query1->IsEmpty()){ //Обновить запись свежими данными Query1->SQL->Text="UPDATE table1 SET Field2="+v2+" WHERE Field1="+v1; try{Query1->ExecSQL();} catch ( ... ){/*это никогда не случается*/} } } catch ( ... ){/*это никогда не случается*/} } VCL грязно работает? В чем тут дело и как победить? |
|||
|
||||
Дрон |
|
|||
![]() Java-ненавистник :) ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3179 Регистрация: 29.12.2002 Где: Санкт-Петербург Репутация: 10 Всего: 92 |
Решил проверить твой код, хотя и не очень шарю в БД. Наткнулся на интересную вещь.
1. Заключил всё в цикл и проверил (память считал Диспетчером задач): Итак за 5000 итераций сожрал 20Мб памяти. Потом я создал ему файл table1.dbf и на 5000 итераций ушло 5Мб памяти. Дальше решил проверить в чём дело. Закомментировал все обращения к Query -- всё в порядке, сколько было при запуске столько и остаётся. 2. А дальше возникла идея. Написал я в первом блоке try, код вызывающий деление на 0 -- а это тоже исключение. Ну и запустил (при этом опять же БЕЗ обращений к Query). На 50000 итераций ушло около 3Мб памяти (т.е. при запуске было ~5Мб, после прогона цикла стало ~8Мб). 3. Потом ещё проверил простым throw 0. А вот он, как оказалось, память не кушает. 4. Делаем выводы: Память жрут исключения. Но не по своей природе, а из-за какой-то хитрой фичи товарищей из Borland. ![]() Почему? Не знаю. P.S. Может быть, этот Диспетчер не правильно память меряет. P.P.S. По своей природе они (исключения) тормозят программу. Даже throw 0 замедлял прогон цикла где-то в 10 раз... Но это уже отдельный разговор. -------------------- Да. Именно так. |
|||
|
||||
VisualCraft |
|
|||
Новичок Профиль Группа: Участник Сообщений: 44 Регистрация: 24.11.2003 Репутация: нет Всего: нет |
У меня тоже это в цикле, наблюдаю и сердце кровью обливаецца.
Придется алгоритм изменить для минимизации исключений. Но проблема все равно остается, т.к. прога предназначена для круглосуточной работы.... С таким багом это невозможно. |
|||
|
||||
VisualCraft |
|
|||
Новичок Профиль Группа: Участник Сообщений: 44 Регистрация: 24.11.2003 Репутация: нет Всего: нет |
Кстати, там опечатка,
вот так должно быть if(!Query1->IsEmpty()) //Не пуст, но это не принципиально, просто исключений намного больше. У меня то правильно написано. |
|||
|
||||
VisualCraft |
|
|||
Новичок Профиль Группа: Участник Сообщений: 44 Регистрация: 24.11.2003 Репутация: нет Всего: нет |
Может в блоке catch(){}
нужно вызывать какую то неизвестную функцию "уборки мусора"? Что-то ничего такого не нахожу. |
|||
|
||||
Vyacheslav |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2124 Регистрация: 25.3.2002 Где: Москва Репутация: 9 Всего: 59 |
Первое. Если утечки смотрели диспетчере - это еще может быть и не утечки. Если у тебя есть форма в приложении, после цикла минимизируй ее, а потом опять восстанови и посмотри сколько отсталось памяти за программой.
Второе. Убери все строковый константы к в AnsiString константы. Использование неименованных строковых констант - плохой стиль. Кроме того при присвоении этих строковых констант свойствам(на самом то деле мы знаем, что вызываются функции) создаются временные AnsiString переменные, а вот их особождение при генерации исключения совсем не гарантируется Т.е. надо сделать следующее const AnsiString cStr1 = "="INSERT INTO table1(Field1,Field2) VALUES ("; ... и далее по коду использовать их -------------------- С уважением, Вячеслав Ермолаев |
|||
|
||||
Дрон |
|
|||
![]() Java-ненавистник :) ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3179 Регистрация: 29.12.2002 Где: Санкт-Петербург Репутация: 10 Всего: 92 |
А вот на вкладке Быстродействие -- всё равно продолжает уверенно увеличиваться по мере работы цикла с VCL исключением. Забавно было бы если бы винда своповаться начала, да только у меня памяти 512 -- ждать слишком долго ![]() Если кто знает -- разъясните, пожалуйста. Может я в чём-то ошибаюсь? А то ведь странно всё это получается, очень даже странно ![]() Это сообщение отредактировал(а) Дрон - 4.2.2004, 23:57 -------------------- Да. Именно так. |
|||
|
||||
Vyacheslav |
|
||||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2124 Регистрация: 25.3.2002 Где: Москва Репутация: 9 Всего: 59 |
Есть ли у тебя утечка реальная утечка памяти, можно выявить только одним способом - с помощью дебагера. Для С++ Builder проще всего использовать CodeGuard. Если он покажет, то утечка дейсствительно есть. Если не покажет, то скорее всего это особенность работы Windows c памятью.
Насчет использования неименнованных констант, приводящих к созданию скрытых переменных объектов. Вот такой пример вызывает утечку памяти
А вот небольшое изменение, которое утечку ликвидирует
-------------------- С уважением, Вячеслав Ермолаев |
||||
|
|||||
Дрон |
|
|||
![]() Java-ненавистник :) ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3179 Регистрация: 29.12.2002 Где: Санкт-Петербург Репутация: 10 Всего: 92 |
Утечка есть!
CodeGuard молчит. Но зато если вырубить виртуальную память, поназапускать кучу программ так, чтобы свободными осталось мегабайт 20, запустить цикл с исключением и чуть-чуть подождать, то начнутся очень забавные вещи ![]() А что касается решения, то я, кажется, кое-что нашёл:
И тогда всё становится very good. Правда, в help написано, что не надо вызывать метод Free, а надо использовать оператор delete, но как же я его для ссылки-то использую? ![]() И вообще, удивляет то, что нигде не сказано, что после обработки исключения память нужно освобождать вручную. -------------------- Да. Именно так. |
|||
|
||||
VisualCraft |
|
|||
Новичок Профиль Группа: Участник Сообщений: 44 Регистрация: 24.11.2003 Репутация: нет Всего: нет |
Спасибо Дрон!
А я нашел аналогичный пример для VC++ Там как раз это сказано слегка. Век живи век учись. catch(СException *e){e->Delete();} |
|||
|
||||
VisualCraft |
|
|||
Новичок Профиль Группа: Участник Сообщений: 44 Регистрация: 24.11.2003 Репутация: нет Всего: нет |
Шутка юмора
Кстати, це не кажется Вам странным шо в выжуал Сы усе на Цэ начинаецца ))))))))))))))))))) Цэ эксэпн ! Я и без них бачу шо цэ эксэпшн... |
|||
|
||||
Puksant |
|
|||
Unregistered |
У меня похожая беда, но код
try{ ... } catch(Exception &e){ ... e.Free(); // вот тут } выдает нарушение доступа к памяти. Если можно пример с реальным кодом. |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |