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

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


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

1 正常使用场景

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

?





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

#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\n", 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检测内存泄漏输出如下:

?




[email protected]:~/dev/test$ gcc -o mysql mysql.c -lmysqlclient

[email protected]:~/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() 函数:

?





1

2

3

4

5

//codes

    mysql_free_result(result);

    mysql_close(conn);

    mysql_library_end();

// codes

  然后用valgrind检测内存泄漏:

?




[email protected]:~/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 <[email protected]>

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

HTML generated by org-mode 6.33x in emacs 23

时间: 2024-10-11 20:04:05

MySQL C 客户端的内存泄漏问题的相关文章

关于Mysql com.mysql.jdbc.StatementImpl$CancelTask内存泄漏问题及解决办法

近来在负责公司短信网关的维护及建设,随着公司业务发展对短信依赖越来越严重了,短信每天发送量也比以前每天40多w发送量暴增到每天达到200w发送量.因为是采用Java做发送底层,压力递增情况下不可避免的面对内存问题.在发送量接近200w情况下,出现内存泄露问题了. 经过对系统运行检查发现: 1)每次重启系统3-4个小时后,均发现一点不稳定: 2)在3-4个小时后,出现out of memory的错误:java.lang.OutOfMemoryError: GC overhead limit exc

JS内存泄漏 和Chrome 内存分析工具简介(摘)

原文地址:http://web.jobbole.com/88463/ JavaScript 中 4 种常见的内存泄露陷阱 原文:Sebastián Peyrott 译文:伯乐在线专栏作者 - ARIGATO 链接:http://web.jobbole.com/88463/ 点击 → 了解如何加入专栏作者 了解 JavaScript 的内存泄露和解决方式! 在这篇文章中我们将要探索客户端 JavaScript 代码中常见的一些内存泄漏的情况,并且学习如何使用 Chrome 的开发工具来发现他们.读

Android内存泄漏检测与MAT使用

内存泄漏基本概念 内存检测这部分,相关的知识有JVM虚拟机垃圾收集机制,类加载机制,内存模型等.编写没有内存泄漏的程序,对提高程序稳定性,提高用户体验具有重要的意义.因此,学习java利用java编写程序的时候,要特别注意内存泄漏相关的问题.虽然JVM提供了自动垃圾回收机制,但是还是有很多情况会导致内存泄漏. 内存泄漏主要原因就是一个生命周期长的对象,持有了一个生命周期短的对象的引用.这样,会导致短的对象在该回收时候无法被回收.Android中比较典型的有:1.静态变量持有Activity的co

Tomcat如何检测内存泄漏

一般情况下,如果我们重启web应用是通过重启tomcat的话,则不存在内存泄漏问题.但如果不重启tomcat而对web应用进行重加载则可能会导致内存泄漏,因为重加载后有可能会导致原来的某些内存无法让GC回收,例如web应用使用了JDBC,驱动会进行注册,当web应用停止时没有反注册就会导致内存泄漏. 看看是什么原因导致tomcat内存泄漏的.这个要从热部署开始说起,因为tomcat提供了不必重启容器而只需重启web应用以达到热部署的功能,其实现是通过定义一个WebappClassLoader类加

轻松排查线上Node内存泄漏问题

I. 三种比较典型的内存泄漏 一. 闭包引用导致的泄漏 这段代码已经在很多讲解内存泄漏的地方引用了,非常经典,所以拿出来作为第一个例子,以下是泄漏代码: 'use strict'; const express = require('express'); const app = express(); //以下是产生泄漏的代码 let theThing = null; let replaceThing = function () { let leak = theThing; let unused =

Java内存泄漏分析与解决方案

Java内存泄漏是每个Java程序员都会遇到的问题,程序在本地运行一切正常,可是布署到远端就会出现内存无限制的增长,最后系统瘫痪,那么如何最快最好的检测程序的稳定性,防止系统崩盘,作者用自已的亲身经历与各位网友分享解决这些问题的办法. 作为Internet最流行的编程语言之一,Java现正非常流行.我们的网络应用程序就主要采用Java语言开发,大体上分为客户端.服务器和数据库三个层次.在进入测试过程中,我们发现有一个程序模块系统内存和CPU资源消耗急剧增加,持续增长到出现java.lang.Ou

100%正确的内存泄漏分析工具 &#160; &#160; &nbsp; --------tMemMonitor (TMM)

C/C++由于灵活.高效的优点一直以来都是主流的程序设计语言之一,但是其内存的分配与释放均由程序员自己管理,当由于疏忽或错误造成程序未能释放不再使用的内存时就会造成内存泄漏.在大型.复杂的应用程序中,内存泄漏往往是最常见的问题,因而及时解决内存泄漏非常必要.tMemMonitor (TMM)作为一个专业.准确.易用的内存泄漏分析工具,可以帮助C/C++程序员迅速地解决内存泄漏这个令人头疼的问题. TMM下载地址: 一.开发背景 目前市面上已有一些Windows平台下的内存泄漏动态检测工具,比如U

SGI STL内存配置器(一):内存泄漏?

阅读了Alexander大神的SGI STL源码,膜拜,很高质量的源码,获益匪浅.温故而知新!下文中所有STL如无特殊说明均指SGI版本实现. STL 内存配置器 STL对内存管理最核心部分我觉得是它将C++对象创建过程分解为构造.析构和内存分配.释放!摆脱了由于频繁调用new或malloc函数向操作系统申请空间而造成的低效.其中析构操作时对具有non-trival.trival 析构函数的class区别对待也提高了效率.至于SGI的两级配置器结构则属于锦上添花的类型. STL两级结构的内存配置

Java_内存泄漏_实例1

版权声明:本文为博主原创文章,未经博主允许不得转载. 记一次压测时Java内存泄漏问题的发现过程(2017-08-14) [前篇] ①20170811进行A系统与B系统之间的会话功能进行压测,加上脚本准备期间的聊天消息,预计累计聊天30w+条消息: ②20170814原计划加大量对会话功能进行压测,情况如下: [应用表现] ①B系统前台打开报错"504": ②查看后台应用CPU情况,CPU利用率高达700+%(8核): ③查看后台内存情况,持续FullGC,且一次FullGC的时长在9