valgrind是linux下对C++和C程序进行内存泄露检测的工具,除了内存检测,valgrind还提供了很多其他的功能,这里主要介绍下valgrind的内存检测的功能。

  首先是文件的下载,valgrind的官方网址是http://valgrind.org/,最新版本的valgrind是3.9,下载地址如下:http://valgrind.org/downloads/。下载好的文件是tar.bz2格式的文件——valgrind-3.9.0.tar.bz2,linux下可以使用tar命令对压缩包进行解压,命令如下:

  

1
tar jxf valgrind-3.9.0.tar.bz2

  解压后,需要对软件进行编译安装,进入解压目录,执行配置命令

1
./configure

  可以指定路径安装,使用 --prefix + 路径 ,默认的安装路径为/usr/local/bin,如果指定了安装路径,后续需要把valgrind的安装路径配置到PATH环境变量中,接下来是编译安装,执行下面的命令

1
make install

  如果执行命令时发现没有权限创建目录,可以使用管理员权限执行,Ubuntu下使用sudo命令即可,安装完成,执行valgrind --version,如果有版本信息出现,就安装成功,否则是安装失败。

1
2
3
mengpl@mengpl-virtual-machine:/usr/local$ valgrind --version
valgrind-3.9.0
mengpl@mengpl-virtual-machine:/usr/local$

  安装过程中,还遇到另外一个问题

1
2
3
4
5
6
7
8
9
valgrind --leak-check=yes ls -l
==7674== Memcheck, a memory error detector
==7674== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==7674== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==7674== Command: ls -l
==7674==
 
valgrind:  Fatal error at startup: a function redirection
valgrind:  which is mandatory for this platform-tool combination

  此时需要安装libc6-dbg库,Ubuntu下的安装命令为:

1
sudo apt-get install libc6-dbg

  正常使用valgrind检测内存的输出如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
mengpl@mengpl-virtual-machine:/usr/local$ valgrind --leak-check=yes ls
==8260== Memcheck, a memory error detector
==8260== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==8260== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info
==8260== Command: ls
==8260==
bin  etc  games  include  lib  man  sbin  share  src
==8260==
==8260== HEAP SUMMARY:
==8260==     in use at exit: 21,373 bytes in 15 blocks
==8260==   total heap usage: 50 allocs, 35 frees, 58,571 bytes allocated
==8260==
==8260== LEAK SUMMARY:
==8260==    definitely lost: 0 bytes in 0 blocks
==8260==    indirectly lost: 0 bytes in 0 blocks
==8260==      possibly lost: 0 bytes in 0 blocks
==8260==    still reachable: 21,373 bytes in 15 blocks
==8260==         suppressed: 0 bytes in 0 blocks
==8260== Reachable blocks (those to which a pointer was found) are not shown.
==8260== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==8260==
==8260== For counts of detected and suppressed errors, rerun with: -v
==8260== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

  使用valgrind对程序进行分析,主要的使用就是内存泄露的分析,也是valgrind默认的工具,valgrind的具体用法,请看man手册,我这里只介绍一种用法,一条命令

1
valgrind --leak-check=full --show-leak-kinds=all -v

  这个命令 + 需要测试的程序,就可以输出一套valgrind的统计报告,下面我重点介绍下对于报告的分析,由于我这个程序比较复杂,里面执行到了很多的内容,我把程序的最终内容进行了归类,主要分为四部分的内容:

  1)内存泄露统计

1
2
3
4
5
6
==6622== LEAK SUMMARY:
==6622==    definitely lost: 1,636 bytes in 9 blocks
==6622==    indirectly lost: 9,421 bytes in 92 blocks
==6622==      possibly lost: 186,418 bytes in 840 blocks
==6622==    still reachable: 728,283 bytes in 1,917 blocks
==6622==         suppressed: 0 bytes in 0 blocks

  2、错误统计

1
ERROR SUMMARY: 3465 errors from 1182 contexts (suppressed: 2 from 2)

  3、内存泄露明细

1
2
3
4
5
6
7
8
9
10
11
12
13
==6622== 152 bytes in 19 blocks are indirectly lost in loss record 1,814 of 1,979
==6622==    at 0x4C2C857: malloc (vg_replace_malloc.c:291)
==6622==    by 0x7614CDB: link_nfa_nodes (regex_internal.c:1000)
==6622==    by 0x761D115: re_compile_internal (regcomp.c:1227)
==6622==    by 0x7620E7E: regcomp (regcomp.c:506)
==6622==    by 0xCE694B5: sal::routecfg::CalRouteHId(long longint&) (routesalcfg_info.cpp:555)
==6622==    by 0xFC15A46: MRoute::CalcHorIdByMajorDim(long long) (route_common.cpp:141)
==6622==    by 0xFC38736: MRoute::CIRouteImp::query_routeByStr(SOBSession*, short const&, std::string const&, std::string const&, MRouteDef::SRouteInfo&, CBSErrorMsg&) (route_inf_sdl_i.cpp:411)
==6622==    by 0xFC40E59: MRoute::SearchDbRouteSync(std::string const&, MRouteDef::SRouteInfo&) (route_interface.cpp:10)
==6622==    by 0xFC48D0D: MRoute::search_routing_info(lua_State*) (route_lua_api.cpp:58)
==6622==    by 0xA3899E5: luaD_precall (ldo.cpp:320)
==6622==    by 0xA389C9D: luaD_call (ldo.cpp:377)
==6622==    by 0xA37F1AF: f_call(lua_State*, void*) (lapi.cpp:800)

  4、错误明细

1
2
3
4
5
6
7
8
9
10
11
12
13
==6622== Use of uninitialised value of size 8
==6622==    at 0x9643FD8: ztcedecb (in /opt/oracle/product/10.2.0/client_1/lib/libclntsh.so.11.1)
==6622==    by 0x96439C1: ztcedencbk (in /opt/oracle/product/10.2.0/client_1/lib/libclntsh.so.11.1)
==6622==    by 0x9643126: ztcebn (in /opt/oracle/product/10.2.0/client_1/lib/libclntsh.so.11.1)
==6622==    by 0x9642C46: ztcen (in /opt/oracle/product/10.2.0/client_1/lib/libclntsh.so.11.1)
==6622==    by 0x7DDE0C8: ztceenc (in /opt/oracle/product/10.2.0/client_1/lib/libclntsh.so.11.1)
==6622==    by 0x7E91769: ztcrbm (in /opt/oracle/product/10.2.0/client_1/lib/libclntsh.so.11.1)
==6622==    by 0x7E912F3: ztcrbh (in /opt/oracle/product/10.2.0/client_1/lib/libclntsh.so.11.1)
==6622==    by 0x7E911B5: ztcrbp (in /opt/oracle/product/10.2.0/client_1/lib/libclntsh.so.11.1)
==6622==    by 0x7E910BE: ztcr2seed (in /opt/oracle/product/10.2.0/client_1/lib/libclntsh.so.11.1)
==6622==    by 0x7E91081: ztcrseed3 (in /opt/oracle/product/10.2.0/client_1/lib/libclntsh.so.11.1)
==6622==    by 0x7DDECC7: ztcsh (in /opt/oracle/product/10.2.0/client_1/lib/libclntsh.so.11.1)
==6622==    by 0x7D35A08: kpusattr (in /opt/oracle/product/10.2.0/client_1/lib/libclntsh.so.11.1)

  首先要对统计信息进行分析,分为四类信息,我们来看下官方对于这四类的解释:

  1、"definitely lost" means your program is leaking memory -- fix those leaks

    这就是内存泄露,需要修改

  2、"indirectly lost" means your program is leaking memory in a pointer-based structure. (E.g. if the root node of a binary tree is "definitely lost", all the children will be "indirectly lost".) If you fix the "definitely lost" leaks, the "indirectly lost" leaks should go away.

    这个意思就是说,泄露的内存是一个指针,也就是我们平常讲的野指针的问题

  3、"still reachable" means your program is probably ok -- it didn’t free some memory it could have. This is quite common and often reasonable. Don’t use --show-reachable=yes if you don’t want to see these reports.

    你的程序可能是好的,意思是,在程序没有结束之前,这部分内存一直都没有释放

  4、"suppressed" means that a leak error has been suppressed. There are some suppressions in the default suppression files. You can ignore suppressed errors.

    这个可以直接忽略

  内存泄露的明细中,会表示出来每一个可能存在内存泄露的地方,可以逐个进行分析,当遇到情况比较多的情况,可以对这些进行分类,在具体分析代码。

  错误明细中,也会存在几种情况,我例子中提到的Use of uninitialised value of size 8 内存没有初始化等。具体的valgrind的用法,推荐一篇文件

https://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/

  这里面介绍的非常详细和周到。

  关于内存增长的问题,还没有定位到具体的位置,后续如果定位到,会把结果补充上来。

一个内存增长问题的分析和处理(二)——valgrind工具的用法的更多相关文章

  1. Linux下利用Valgrind工具进行内存泄露检测和性能分析

    from http://www.linuxidc.com/Linux/2012-06/63754.htm Valgrind通常用来成分析程序性能及程序中的内存泄露错误 一 Valgrind工具集简绍 ...

  2. 【腾讯优测干货分享】如何降低App的待机内存(三)——探索内存增长的原因

    本文来自于腾讯优测公众号(wxutest),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/8BiKIt3frq9Yv9KV5FXlGw 1.3新问题的进一步挖 ...

  3. 线上mysql内存持续增长直至内存溢出被killed分析(已解决)

    来新公司前,领导就说了,线上生产环境Mysql库经常会发生日间内存爆掉被killed的情况,结果来到这第一天,第一件事就是要根据线上服务器配置优化配置,同时必须找出现在mysql内存持续增加爆掉的原因 ...

  4. jvm内存增长问题排查

    jvm内存增长问题排查 排查个jvm 内存占用持续增加的问题,纪录一下,引以为戒. 运维发现应用jvm内存占用在发布后回落,然后持续增高,,dump后分析一下: 占内存的大部分是这种名字相似的bean ...

  5. jvm内存增长问题排查简例

    jvm内存增长问题排查 排查个jvm 内存占用持续增加的问题,纪录一下,引以为戒. 运维发现应用jvm内存占用在发布后回落,然后持续增高,,dump后分析一下: 占内存的大部分是这种名字相似的bean ...

  6. vector内存增长方式

    首先必须要了解vector是一种特殊的数组,因此其内存必然是连续的 其次它的连续是建立在不断地对内存的预分配上的,即不断地销毁当前,重新建立内存,效率有点低.所以存在几个函数capacity, siz ...

  7. Cocos2d-X3.0 刨根问底(四)----- 内存管理源码分析

    本系列文章发表以来得到了很多朋友的关注,小鱼在这里谢谢大家对我的支持,我会继续努力的,最近更新慢了一点,因为我老婆流产了抽了很多时间来照顾她希望大家谅解,并在此预祝我老婆早日康复. 上一篇,我们完整的 ...

  8. Java 中 ThreadLocal 内存泄露的实例分析

    前言 之前写了一篇深入分析 ThreadLocal 内存泄漏问题是从理论上分析ThreadLocal的内存泄漏问题,这一篇文章我们来分析一下实际的内存泄漏案例.分析问题的过程比结果更重要,理论结合实际 ...

  9. jstack(查看线程)、jmap(查看内存)和jstat(性能分析)

    公司内部同事分享的一篇文章 周末看到一个用jstack查看死锁的例子.昨天晚上总结了一下jstack(查看线程).jmap(查看内存)和jstat(性能分析)命令.供大家参考 1.Jstack 1.1 ...

随机推荐

  1. SWD下载调试填坑,SWD连接丢失问题解决

    野火SWD下载器,设置好以后,第一次下载成功,莫名其妙丢失连接,发现在复位状态可以连接(惊奇) 网络上搜索到把Boot0和Boot1置高,就可以把程序下载到RAM里, 能下载以后就好办了,把程序里SW ...

  2. 合唱队形(LIS)

    合唱队形    OpenJ_Bailian - 2711 N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学不交换位置就能排成合唱队形. 合唱队形是指这样的一种队形:设K位同 ...

  3. 使用google的GSON解析json格式的数据

    GSON是谷歌提供的开源库,用来解析Json格式的数据,非常好用.如果要使用GSON的话,则要先下载gson-2.2.4.jar这个文件,如果是在Android项目中使用,则在Android项目的li ...

  4. Eclipse 中svn的合并与同步

    Eclipse 中svn的合并与同步: 1.  从主干拉取到分支: 然后一直下一步,到完成就OK了. 2.  从分支代码合并到主干: 2.1.先将本地需要提交更新的代码提交更新到svn分支去 2.2. ...

  5. iphone传感器

    传感器 什么是传感器 传感器是一种感应\检测装置, 目前已经广泛应用于智能手机上 传感器的作用 用于感应\检测设备周边的信息 不同类型的传感器, 检测的信息也不一样 iPhone中的下面现象都是由传感 ...

  6. spring AOP操作

    在spring进行AOP操作,使用aspectj实现 一.aspectj准备 aspectj不是spring的一部分,和spring一起使用进行AOP的操作 1.除了spring基本的jar包还需要导 ...

  7. tf.InteractiveSession()与tf.Session()

    tf.InteractiveSession():它能让你在运行图的时候,插入一些计算图,这些计算图是由某些操作(operations)构成的.这对于工作在交互式环境中的人们来说非常便利,比如使用IPy ...

  8. Linux 3 -grep

    七. grep家族: 1. grep退出状态: 0: 表示成功: 1: 表示在所提供的文件无法找到匹配的pattern: 2: 表示参数中提供的文件不存在. 见如下示例: /> grep 'ro ...

  9. 《程序员代码面试指南》第二章 链表问题 删除中间节点和a/b处节点

    题目 例如 1-2-3-4 删除2,1-2-3-4-5 删除3 例如 a=1,b =2 java代码 /** * @Description:删除中间节点和a/b处节点 * @Author: lizho ...

  10. 321list,元组,range**数字是不可迭代的!

    一.list(列表) 列表是python中的基础数据类型之一,他是以[]括起来,每个元素以逗号隔开,而且他里面可以存放各种数据类型.列表相比于字符串,不仅可以储存不同的数据类型,而且可以储存大量数据, ...