C ++ Visual Studio mysqlpp серьезная утечка памяти

Я почесал голову над этим в течение последнего месяца и до сих пор не могу понять, что происходит.

Проблема в том, что у меня очень серьезная утечка памяти в приложении C ++, работающем на Windows Server 2008, скомпилированном с использованием Visual Studio 2005. Это управляемый проект. Приложение запускается на уровне 5-6 МБ (в соответствии с диспетчером задач) и начинает демонстрировать признаки сбоя около отметки ~ 200 МБ. Я знаю, что диспетчер задач — это грубый инструмент, но, учитывая масштаб утечки, он вполне подходит для использования.

Я сузил проблему до взаимодействия с базой данных MySQL. Если приложение не взаимодействует с базой данных, нет утечки памяти.

Все взаимодействия с базой данных используют mysql ++. Я следовал инструкциям по сборке на страницах man на tangentsoft.net.

Мы оценили код для обеспечения безопасности потока (то есть мы убедились, что каждый поток использует только объект mysqlpp из этого потока, но не из других) и проверили, чтобы все деструкторы вызывались для любых динамически генерируемых объектов, созданных с использованием ‘new’.

Просматривая в Интернете, я продолжаю видеть различные отчеты от пользователей класса mysqlpp, которые указывают, что где-то есть утечка. В частности, обсуждалась утечка Win C API при использовании mysqlpp:

http://www.phpmarks.com/6-mysql-plus/ffd713579bbb1c3e.htm

Это обсуждение, похоже, завершается исправлением, однако, когда я пытаюсь исправить исправления в моем приложении, оно все равно протекает.

Я реализовал версию приложения, упомянутую в ветке выше, но с некоторыми советами из справочных страниц:

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
while (true)
{
//Initialise MySQL API
mysql_library_init(0, NULL, NULL);

Sleep(50);
//Connect to Database.
mysqlpp::Connection c;
c.connect("myDatabase","localhost","username","password");

Sleep(50);
//Disconnect from Database
c.disconnect();

Sleep(50);
//Free memory allocated to the heap for this thread
c.thread_end();

Sleep(50);
//Free any memory allocated by MySQL C API
mysql_library_end();

Sleep(50);
}
return 1;
}

Я добавил Sleep (50) только для того, чтобы регулировать каждую стадию цикла, чтобы у каждой функции было время «успокоиться». Я знаю, что, вероятно, в этом нет необходимости, но, по крайней мере, таким образом я могу устранить это как причину.

Тем не менее, эта программа протекает довольно быстро (~ 1 Мб в час).

Я видел подобные вопросы, которые мне задавали в нескольких местах, без каких-либо выводов 🙁

Так что я не одинок в этом вопросе. Мне приходит в голову, что класс mysqlpp имеет репутацию полезного и поэтому должен быть достаточно надежным. Учитывая, что это так, я до сих пор не вижу, что я сделал неправильно. У кого-нибудь есть опыт работы с mysqlpp с Visual Studio 2005, который может пролить свет на проблему?

Ура,
Адам.

РЕДАКТИРОВАТЬ

Я создал другой пример, используя указатель, на случай, если c дублируется в цикле:

//LEAKY
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
mysqlpp::Connection * c;

while (true)
{
mysql_library_init(0, NULL, NULL);

c = new mysqlpp::Connection;

Sleep(50);

c->connect("myDatabase","localhost","username","password");

Sleep(50);
c->disconnect();

Sleep(50);
c->thread_end();

Sleep(50);
mysql_library_end();

Sleep(50);

delete c;
c = NULL;
}
return 1;
}

Это также утечки. Затем я создал контрольный пример, основанный на этом коде, который не протекает вообще:

//NOT LEAKY
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
char * ch;

while (true)
{
mysql_library_init(0, NULL, NULL);

//Allocate 4000 bytes
ch = new char [4000];

Sleep(250);

mysql_library_end();

delete ch;
ch = NULL;

}
return 1;
}

Обратите внимание, что я также оставил вызовы MySQL C API здесь, чтобы доказать, что это не является причиной утечки. Затем я создал пример с использованием указателя, но без вызовов для подключения / отключения:

//NOT LEAKY
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{

mysqlpp::Connection * c;

while (true)
{
mysql_library_init(0, NULL, NULL);

c = new mysqlpp::Connection;
Sleep(250);

mysql_library_end();

delete c;
c = NULL;
}

return 1;
}

Это не утечка.

Таким образом, разница заключается только в использовании методов mysqlpp :: connect / disconnect. Я покопаюсь в самом классе mysqlpp и попытаюсь выяснить, в чем дело.

Ура,
Адам.

РЕДАКТИРОВАТЬ

Вот пример кода с утечкой, где выполняются проверки.

//LEAKY
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
mysqlpp::Connection * c;

while (true)
{
mysql_library_init(0, NULL, NULL);

c = new mysqlpp::Connection;

Sleep(50);

if ( c->connect("myDatabase","localhost","username","password") == false )
{
cout << "Connection Failure";
return 0;
}

Sleep(50);
c->disconnect();

Sleep(50);
c->thread_end();

Sleep(50);
mysql_library_end();

Sleep(50);

delete c;
c = NULL;
}
return 1;
}

Ура,
Адам.

1

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]