Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Общие вопросы > Прога на С++ Builder 5.0 кушает память. Помогите. |
Автор: VisualCraft 3.2.2004, 03:57 |
//Подготовка 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 грязно работает? В чем тут дело и как победить? |
Автор: Дрон 4.2.2004, 12:49 |
Решил проверить твой код, хотя и не очень шарю в БД. Наткнулся на интересную вещь. 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 4.2.2004, 17:26 |
У меня тоже это в цикле, наблюдаю и сердце кровью обливаецца. Придется алгоритм изменить для минимизации исключений. Но проблема все равно остается, т.к. прога предназначена для круглосуточной работы.... С таким багом это невозможно. |
Автор: VisualCraft 4.2.2004, 17:36 |
Кстати, там опечатка, вот так должно быть if(!Query1->IsEmpty()) //Не пуст, но это не принципиально, просто исключений намного больше. У меня то правильно написано. |
Автор: VisualCraft 4.2.2004, 17:42 |
Может в блоке catch(){} нужно вызывать какую то неизвестную функцию "уборки мусора"? Что-то ничего такого не нахожу. |
Автор: Vyacheslav 4.2.2004, 17:57 |
Первое. Если утечки смотрели диспетчере - это еще может быть и не утечки. Если у тебя есть форма в приложении, после цикла минимизируй ее, а потом опять восстанови и посмотри сколько отсталось памяти за программой. Второе. Убери все строковый константы к в AnsiString константы. Использование неименованных строковых констант - плохой стиль. Кроме того при присвоении этих строковых констант свойствам(на самом то деле мы знаем, что вызываются функции) создаются временные AnsiString переменные, а вот их особождение при генерации исключения совсем не гарантируется Т.е. надо сделать следующее const AnsiString cStr1 = "="INSERT INTO table1(Field1,Field2) VALUES ("; ... и далее по коду использовать их |
Автор: Дрон 4.2.2004, 23:56 | ||
А вот на вкладке Быстродействие -- всё равно продолжает уверенно увеличиваться по мере работы цикла с VCL исключением. Забавно было бы если бы винда своповаться начала, да только у меня памяти 512 -- ждать слишком долго ![]() Если кто знает -- разъясните, пожалуйста. Может я в чём-то ошибаюсь? А то ведь странно всё это получается, очень даже странно ![]() |
Автор: Vyacheslav 5.2.2004, 10:14 | ||||
Есть ли у тебя утечка реальная утечка памяти, можно выявить только одним способом - с помощью дебагера. Для С++ Builder проще всего использовать CodeGuard. Если он покажет, то утечка дейсствительно есть. Если не покажет, то скорее всего это особенность работы Windows c памятью. Насчет использования неименнованных констант, приводящих к созданию скрытых переменных объектов. Вот такой пример вызывает утечку памяти
А вот небольшое изменение, которое утечку ликвидирует
|
Автор: Дрон 5.2.2004, 12:54 | ||
Утечка есть! CodeGuard молчит. Но зато если вырубить виртуальную память, поназапускать кучу программ так, чтобы свободными осталось мегабайт 20, запустить цикл с исключением и чуть-чуть подождать, то начнутся очень забавные вещи ![]() А что касается решения, то я, кажется, кое-что нашёл:
И тогда всё становится very good. Правда, в help написано, что не надо вызывать метод Free, а надо использовать оператор delete, но как же я его для ссылки-то использую? ![]() И вообще, удивляет то, что нигде не сказано, что после обработки исключения память нужно освобождать вручную. |
Автор: VisualCraft 5.2.2004, 13:58 |
Спасибо Дрон! А я нашел аналогичный пример для VC++ Там как раз это сказано слегка. Век живи век учись. catch(СException *e){e->Delete();} |
Автор: VisualCraft 5.2.2004, 14:02 |
Шутка юмора Кстати, це не кажется Вам странным шо в выжуал Сы усе на Цэ начинаецца ))))))))))))))))))) Цэ эксэпн ! Я и без них бачу шо цэ эксэпшн... |
Автор: Puksant 16.8.2004, 13:40 |
У меня похожая беда, но код try{ ... } catch(Exception &e){ ... e.Free(); // вот тут } выдает нарушение доступа к памяти. Если можно пример с реальным кодом. |