Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Прога на С++ Builder 5.0 кушает память. Помогите. Место локализовано, но что делать? 
:(
    Опции темы
VisualCraft
  Дата 3.2.2004, 03:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 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 грязно работает?
В чем тут дело и как победить?
PM MAIL   Вверх
Дрон
Дата 4.2.2004, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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. smile.gif
Почему? Не знаю.

P.S.
Может быть, этот Диспетчер не правильно память меряет.

P.P.S.
По своей природе они (исключения) тормозят программу. Даже throw 0 замедлял прогон цикла где-то в 10 раз... Но это уже отдельный разговор.



--------------------
Да. Именно так.
PM   Вверх
VisualCraft
Дата 4.2.2004, 17:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



У меня тоже это в цикле, наблюдаю и сердце кровью обливаецца.
Придется алгоритм изменить для минимизации исключений.
Но проблема все равно остается, т.к. прога предназначена для круглосуточной работы....
С таким багом это невозможно.
PM MAIL   Вверх
VisualCraft
Дата 4.2.2004, 17:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Кстати, там опечатка,
вот так должно быть if(!Query1->IsEmpty()) //Не пуст,
но это не принципиально, просто исключений намного больше.
У меня то правильно написано.
PM MAIL   Вверх
VisualCraft
Дата 4.2.2004, 17:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Может в блоке catch(){}
нужно вызывать какую то неизвестную функцию "уборки мусора"?
Что-то ничего такого не нахожу.
PM MAIL   Вверх
Vyacheslav
Дата 4.2.2004, 17:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 9
Всего: 59



Первое. Если утечки смотрели диспетчере - это еще может быть и не утечки. Если у тебя есть форма в приложении, после цикла минимизируй ее, а потом опять восстанови и посмотри сколько отсталось памяти за программой.

Второе. Убери все строковый константы к в AnsiString константы. Использование неименованных строковых констант - плохой стиль. Кроме того при присвоении этих строковых констант свойствам(на самом то деле мы знаем, что вызываются функции) создаются временные AnsiString переменные, а вот их особождение при генерации исключения совсем не гарантируется
Т.е. надо сделать следующее

const AnsiString cStr1 = "="INSERT INTO table1(Field1,Field2) VALUES (";
...
и далее по коду использовать их


--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Дрон
Дата 4.2.2004, 23:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


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

Репутация: 10
Всего: 92



Цитата
после цикла минимизируй ее, а потом опять восстанови
Да, действительно, на вкладке Процессы при этом уменьшается кол-во используемой памяти. И вообще на той вкладке как-то странно считается используемая память...

А вот на вкладке Быстродействие -- всё равно продолжает уверенно увеличиваться по мере работы цикла с VCL исключением.
Забавно было бы если бы винда своповаться начала, да только у меня памяти 512 -- ждать слишком долго smile.gif

Если кто знает -- разъясните, пожалуйста. Может я в чём-то ошибаюсь? А то ведь странно всё это получается, очень даже странно smile.gif

Это сообщение отредактировал(а) Дрон - 4.2.2004, 23:57


--------------------
Да. Именно так.
PM   Вверх
Vyacheslav
Дата 5.2.2004, 10:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 9
Всего: 59



Есть ли у тебя утечка реальная утечка памяти, можно выявить только одним способом - с помощью дебагера. Для С++ Builder проще всего использовать CodeGuard. Если он покажет, то утечка дейсствительно есть. Если не покажет, то скорее всего это особенность работы Windows c памятью.
Насчет использования неименнованных констант, приводящих к созданию скрытых переменных объектов. Вот такой пример вызывает утечку памяти
Код

сlass MyClass
{
 public:
   MyClass(String );
   ~MyClass(void);
 private:
   String FileName;
   void ErrFunc(void);
};
//---------------------------------------------------------------------------
MyClass::MyClass(String aFileName) :FileName(aFileName)
{
   throw 1;
}
//---------------------------------------------------------------------------
MyClass::~MyClass(void)
{
 ShowMessage("destructor");
}
//---------------------------------------------------------------------------

void __fastcall TForm2::Button1Click(TObject *Sender)
{
   for(;;)
 try
 {
  new MyClass("hghghghghghghghghghghghghghghghghghghghgh" );
 }
 catch(...){}
}


А вот небольшое изменение, которое утечку ликвидирует
Код

void __fastcall TForm2::Button1Click(TObject *Sender)
{
 AnsiString Test = "hghghghghghghghghghghghghghghghghghghghgh";
 for(;;)
 try
 {
  new MyClass(Test );
 }
 catch(...){}
}




--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Дрон
Дата 5.2.2004, 12:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


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

Репутация: 10
Всего: 92



Утечка есть!
CodeGuard молчит. Но зато если вырубить виртуальную память, поназапускать кучу программ так, чтобы свободными осталось мегабайт 20, запустить цикл с исключением и чуть-чуть подождать, то начнутся очень забавные вещи smile.gif

А что касается решения, то я, кажется, кое-что нашёл:
Код
try{
...
}
catch(Exception &e){
...
e.Free(); // вот оно!
}

И тогда всё становится very good.
Правда, в help написано, что не надо вызывать метод Free, а надо использовать оператор delete, но как же я его для ссылки-то использую? smile.gif
И вообще, удивляет то, что нигде не сказано, что после обработки исключения память нужно освобождать вручную.



--------------------
Да. Именно так.
PM   Вверх
VisualCraft
Дата 5.2.2004, 13:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Спасибо Дрон!
А я нашел аналогичный пример для VC++
Там как раз это сказано слегка. Век живи век учись.
catch(СException *e){e->Delete();}


PM MAIL   Вверх
VisualCraft
Дата 5.2.2004, 14:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Шутка юмора
Кстати, це не кажется Вам странным шо в выжуал Сы
усе на Цэ начинаецца )))))))))))))))))))
Цэ эксэпн ! Я и без них бачу шо цэ эксэпшн...
PM MAIL   Вверх
Puksant
Дата 16.8.2004, 13:40 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











У меня похожая беда, но код

try{
...
}
catch(Exception &e){
...
e.Free(); // вот тут
}
выдает нарушение доступа к памяти. Если можно пример с реальным кодом.
  Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




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


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

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