C ++ Visual Studio mysqlpp严重内存泄漏

时间:2012-11-20 18:39:18

标签: c++ memory-leaks visual-studio-2005 mysqlpp

过去一个月我一直在摸不着头脑,我仍然无法弄清楚发生了什么。

问题是我在使用Visual Studio 2005编译的Windows Server 2008上运行的C ++应用程序上存在非常严重的内存泄漏。这是一个托管项目。应用程序从大约5-6MB开始(根据任务管理器)并开始出现大约200MB标记的故障症状。我知道任务管理器是一个粗糙的工具,但考虑到泄漏的规模,似乎可以使用。

我已将问题缩小到MySQL数据库交互。如果应用程序不与数据库交互,则不会泄漏内存。

所有数据库交互都使用mysql ++。我已经按照tangentsoft.net上的手册页中的构建说明进行操作。

我们已经评估了线程安全的代码(也就是说,我们确保每个线程只使用来自该线程的mysqlpp对象,而不是其他线程)并检查以确保为使用'new创建的任何动态生成的对象调用所有析构函数”。

在互联网上查看我一直看到来自mysqlpp类用户的各种报告,表明某处有泄漏。特别是,讨论了当使用mysqlpp时Win C API如何泄漏:

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)只是为了限制循环的每个阶段,以便每个函数都有时间“安定下来”。我知道这可能没有必要,但至少这样我可以将其作为一个原因消除。

然而,这个程序泄漏得非常快(每小时约1mb)。

我在一些地方看到过与我相似的问题,没有得出任何结论:(

所以我并不孤单。在我看来,mysqlpp类具有实用性的声誉,因此必须非常强大。既然如此,我仍然看不出我做错了什么。有没有人对Visual Studio 2005有一些mysqlpp的经验可能会解决这个问题?

干杯, 亚当。

修改

我使用指针创建了另一个示例,以防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;
}

干杯, 亚当。

0 个答案:

没有答案