• MySQL C 客户端的内存泄漏问题


    我们的一个服务器软件在线上环境运行时出现了内存缓慢增长的问题。

    用valgrind测试 MySQL的C客户端mysqlclient发现,它在正常的使用中会被valgrind报出存在内存泄漏。

    1 正常使用场景

    下面的代码是使用mysqlclient读取数据的最常用的代码

    #include <mysql/mysql.h>
    #include <stdio.h>
    
    int main()
    {
        MYSQL       *conn;
        MYSQL_RES   *result;
        MYSQL_ROW    row;
        char        *w;
    
    
        conn = mysql_init(NULL);
        mysql_real_connect(conn, "127.0.0.1", "root", "", "db_test", 3306, NULL, 0);
    
        mysql_query(conn, "select id from test");
    
        result = mysql_store_result(conn);
        if (result == NULL) {
            printf("%d:%s
    ", mysql_errno(conn), mysql_error(conn));
            goto out;
        }
    
        while ((row = mysql_fetch_row(result))) {
            w = row[0];
        }
    
     out:
        mysql_free_result(result);
        mysql_close(conn);
        mysql_library_end();
    
        return 0;
    }
    

       

    上面的代码用valgrind检测内存泄漏输出如下:

    cobbliu@ubuntu:~/dev/test$ gcc -o mysql mysql.c -lmysqlclient
    cobbliu@ubuntu:~/dev/test$ valgrind --leak-check=full --show-reachable=yes ./mysql
    ==4497== Memcheck, a memory error detector
    ==4497== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
    ==4497== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
    ==4497== Command: ./mysql
    ==4497==
    ==4497==
    ==4497== HEAP SUMMARY:
    ==4497==     in use at exit: 73,872 bytes in 21 blocks
    ==4497==   total heap usage: 84 allocs, 63 frees, 128,626 bytes allocated
    ==4497==
    #
    #        这儿忽略了一部分输出
    #
    ==4497== LEAK SUMMARY:
    ==4497==    definitely lost: 0 bytes in 0 blocks
    ==4497==    indirectly lost: 0 bytes in 0 blocks
    ==4497==      possibly lost: 0 bytes in 0 blocks
    ==4497==    still reachable: 73,872 bytes in 21 blocks
    ==4497==         suppressed: 0 bytes in 0 blocks
    ==4497==
    ==4497== For counts of detected and suppressed errors, rerun with: -v
    ==4497== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
    

      可以看出,在正常的使用场景下,mysqlclient有一部分内存在 mysql_close() 之后并没有被释放。

    2 解决方法

    stackoverflow上的一篇文章提出了解决方法:在 mysql_close() 之后调用 mysql_library_end() 来释放 剩余的内存空间 MySQL开发手册对 mysql_library_end() 的描述如下:

    This function finalizes the MySQL library.
    Call it when you are done using the library (for example, after disconnecting from the server).
    The action taken by the call depends on whether your application is linked to the MySQL client library or the MySQL embedded server library.
    For a client program linked against the libmysqlclient library by using the -lmysqlclient flag, mysql_library_end() performs some memory management to clean up.
    

      

    3 效果检验

    在上面的示例代码中加入 mysql_library_end() 函数:

    //codes 
        mysql_free_result(result);
        mysql_close(conn); 
        mysql_library_end();
    // codes
    

      然后用valgrind检测内存泄漏:

    cobbliu@ubuntu:~/dev/test$ valgrind --leak-check=full --show-reachable=yes ./mysql
    ==4513== Memcheck, a memory error detector
    ==4513== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
    ==4513== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
    ==4513== Command: ./mysql
    ==4513==
    ==4513==
    ==4513== HEAP SUMMARY:
    ==4513==     in use at exit: 0 bytes in 0 blocks
    ==4513==   total heap usage: 84 allocs, 84 frees, 128,626 bytes allocated
    ==4513==
    ==4513== All heap blocks were freed -- no leaks are possible
    ==4513==
    ==4513== For counts of detected and suppressed errors, rerun with: -v
    ==4513== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
    

      可以看出,已经没有未释放的内存了。

    所以对于daemon进程,如果频繁地调用 mysql_init  mysql_close 的话,记得在 mysql_close 之后调用 mysql_library_end() 来释放未被释放的内存

    Author: CobbLiu <cobblau@gmail.com>

    Date: 2014-05-05 13:42:21 CST

    HTML generated by org-mode 6.33x in emacs 23

  • 相关阅读:
    刷题-力扣-剑指 Offer 22. 链表中倒数第k个节点
    刷题-力扣-617. 合并二叉树
    刷题-力扣-1109. 航班预订统计
    刷题-力扣-606. 根据二叉树创建字符串
    刷题-力扣-563. 二叉树的坡度
    扛把子组20191017-8 alpha week 2/2 Scrum立会报告+燃尽图 07
    20191017-7 alpha week 2/2 Scrum立会报告+燃尽图 06
    20191017-6alpha week 2/2 Scrum立会报告+燃尽图 05
    扛把子组20191017-5 alpha week 2/2 Scrum立会报告+燃尽图 04
    记第一次 团建
  • 原文地址:https://www.cnblogs.com/cobbliu/p/3709051.html
Copyright © 2020-2023  润新知