本文将介绍几种内存泄漏检测工具,并通过实际例子介绍一种分析堆内存占用量的工具和方法,帮助定位内存膨胀问题。背景

进程的内存管理是每一个开发者必须要考虑的问题,对于C++程序进程来说,出现问题很多情况下都与内存挂钩。进程崩溃问题通常可以使用gdb等调试工具轻松排查并解决。而对于进程内存膨胀这类问题,原因通常有三个:

1.内存泄漏。

2.分配器管理的空闲内存较多而造成的内存空洞。

3.有未统计使用的未知内存占用。

内存泄漏问题可以使用一些工具来检测。但是对于后两种问题,却一直没有比较通用的方法去确定。本文将介绍几种内存泄漏检测工具,并通过实际例子介绍一种分析堆内存占用量的工具和方法,帮助定位内存膨胀问题。常见内存问题的分析方法

对于内存泄露问题,目前已经有较成熟的工具进行检测,这里简单介绍两个工具:AddressSanitizer和Valgrind。

AddressSanitizer是google开源项目,可以用来检测内存泄漏和其他导致进程崩溃的内存问题。它的优势在于造成的额外CPU占用很小,但是需要重新编译项目,并且在编译的时候添加-fsanitize=address选项。在程序运行时如果有任何内存问题,就会终止进程并且打印出详细的错误信息。如果进程存在内存泄漏会在进程结束后,打印出所有泄漏的内存大小和申请这块内存的调用栈,如下图所示:

AddressSanitizer检测内存泄漏

另一个工具Valgrind的优势在于不需要重新编译,只需要在运行时加上valgrind --leak-check=yes即可。但是它的额外CPU开销会更大,大约是AddressSanitizer的十倍,功能上也不及AddressSanitizer完善。下表是两种工具功能和性能的比较:

AddressSanitizer与Valgrind对比

这两种工具不光能够检测内存泄漏,对于堆栈溢出等问题也有比较好的效果。对于这两个工具更具体的介绍可以参照官方的使用文档:

AddressSanitizer:https://github.com/google/sanitizers/wiki/AddressSanitizer

Valgrind:

而对于后两种原因,我们需要根据不同的分配器区别看待。常见的分配器有glibc默认的ptmalloc,google维护的tcmalloc以及facebook维护的jemalloc等。后两者都自带了内存分析工具(Heap Profiler),可以检测内存泄漏,也可以打印出详细的内存分配情况,对上述三个问题都有比较完善的排查方法,有兴趣可以查看官方文档,都讲得比较详细,这里不再介绍。而glibc默认的ptmalloc却不自带这样的工具,一种排查方法是去了解ptmalloc的实现和结构以后编写程序或者gdb脚本去分析进程的内存结构,我们接下来要介绍的一种内存分析工具就是以这种方法实现的。针对ptmalloc的堆内存内用分析1.环境

58自研的搜索引擎Esearch底层使用C++实现。Esearch在内存管理方面针对不同的场景会有不同的策略。对于对象生命周期有规律,高频分配的场景,Esearch实现了定制的内存池进行管理,并且这些内存都会在日志中统计占用量。而对于对象生命周期不确定,大小不确定的场景,内存池的代价可能高于通用分配器(new/malloc),所以直接使用通用内存分配器来分配。

对于通用分配器的选择,目前Esearch使用的是glibc2.12环境下默认的ptmalloc。之所以未使用tcmalloc或者jemalloc是因为经测试后发现后两者在常见场景下内存占用比ptmalloc要高,而且Esearch中对于内存分配热点已经使用了定制内存池,后两种分配器的优势其实并不明显。对于Ptmalloc完整结构的介绍可以阅读源码或者参阅华庭的《glibc内存管理ptmalloc2源代码分析》,这里只在用到时阐述一下原理,不做过多的介绍。

接下来我们通过一个例子来了解如何分析堆内存的用量。现在有一个realtime_searcher进程如下:

运行中的realtime_searcher进程

可见进程占用总物理内存27G,其中SHR内存占用18G,剩下的物理内存 约9G。

2.工具介绍

这里介绍一个非常强大的内存分析工具——core_analyzer。这是一个基 于core文件的内存分析工具,由Michael Yan开发和维护并且开源在github上。利用它可以对glibc层的ptmalloc结构进行分析,还原进程真实的内存结构。目前core_analyzer支持的glibc2.3,2.4,2.5,2.12-2.23版本下的ptmalloc实现,这些版本对应的ptmalloc结构其实都大同小异。

Core_analyzer工具提供了以下功能:

Core_analyzer用户界面

[0] 打印core文件的基本信息,包括各个线程的信息,和内存段的信息等。

[1] 水平搜索对象的引用

[2] 垂直搜索对象的引用链,直到找到符号表中有调试信息的对象。

[3] 打印线程共享对象

[4] 打印给定地址段的内容

[5] 通过地址查询所属chunk

[6] 打印所给的地址周围的页(意义不明)

[7] 打印整个堆的结构。该结构能够与ptmalloc的结构相对应

[8]、[9]都是打印前N大的chunk,[9]还顺便打印出引用链

[10] 根据它的名字为内存泄漏检测,但实际使用发现不仅耗时而且不正确

[11] 退出

linux进程实际内存大小,Linux进程内存用量分析之堆内存篇相关推荐

  1. linux 设置java内存大小_Linux 下修改Tomcat使用的JVM内存大小

    转自  : http://blog.csdn.net/sully2008/article/details/6457570 我的服务器的配置: # OS specific support.  $var ...

  2. linux查看进程占用的内存大小,查看进程占用内存大小的几种方法,占用内存几种方法...

    查看进程占用内存大小的几种方法,占用内存几种方法 1. pmap -x pid 2. ps -aux | grep 进程名 ps -e -o 'pid,comm,args,pcpu,rsz,vsz,s ...

  3. linux 内核申请内存大小,linux内核常用的内存申请函数

    在读驱动程序时,常遇到内存申请函数.驱动程序属于内核空间,和用户空间用到的内存申请函数不同. 内核空间最常用到的内存申请函数为kmalloc()和kzalloc(). kmalloc()是申请一段内存 ...

  4. 如何查看linux系统的存储空间大小,linux 如何查看硬盘大小,存储空间大小等系统信息及硬件信息...

    一.linux CPU大小 [root@idc ~]# cat /proc/cpuinfo |grep "model name" && cat /proc/cpui ...

  5. Java计算一个对象所占内存大小_Java程序计算各种对象所占内存的大小的方法

    System.out.println("--- Memory Usage:"); /*打印一行字符串---Memory Usage*/ Runtime rt=Runtime.get ...

  6. MAT工具分析java堆内存

    1.根据端口号查询对应进程号 Linux:netstat -nltp|grep 8080 Windows:netstat -aon|findstr 8080 2.dump堆文件 jmap -dump: ...

  7. linux中ls文件内存大小,Linux下用ls和du命令查看文件以及文件夹大小

    webdriver零碎知识点 #零碎知识点,用于记录平时遇到的比较杂的知识点 driver.current_url 获取当前url phantomjs 实现无浏览器界面自动化测试(driver = w ...

  8. linux 一次io大小,linux – AWS EBS中IO操作(IOP)的大小是多少?

    一个I / O操作的大小取决于很多事情.计算应用程序的平均值并不一定是个坏主意. 亚马逊对它们的定义意味着它们的硬件支持256KB块.单个I / O操作是读取或写入一个块.即使软件和硬件块大小匹配,对 ...

  9. linux lv在线缩小大小,Linux使用lvresize扩展或缩减lv大小

    环境:CentOS 6.7 一.新建并挂载目录 /u01 和 /data 1.创建目录挂节点/u01,/data mkdir -p /{u01,data} 2.创建lv,名称是lv_u01,大小10g ...

最新文章

  1. html:漂亮的原生表格_HTML表格:关于它们的所有知识
  2. 干货 | 谷歌BERT模型fine-tune终极实践教程
  3. python 画柱状图-Python 使用 matplotlib 画柱状图教程
  4. php程序中用户名含特殊字符怎么办,php中包含ñ等特殊字符
  5. opengl加载显示3D模型IFC类型文件
  6. python2.7安装pip_RobotFramework安装过程遇到的问题(电脑同时安装python2和3)
  7. javafx 和swing_集成JavaFX和Swing(修订版)
  8. mysql考勤系统设计函数_Mysql实战之员工考勤系统数据库建立
  9. Ubuntu下ffmpeg 捕获屏幕和采集声卡、摄像头、麦克风声音
  10. Hadoop on Mac with IntelliJ IDEA - 5 解决java heap space问题
  11. 企业微服务架构转型-关键诉求
  12. 关于微信unionid理解
  13. Python开源BI工具Superset的搭建与使用
  14. RFID电子标签对于图书管理的应用
  15. bzoj 2101: [Usaco2010 Dec]Treasure Chest 藏宝箱【区间dp】
  16. sun.net.ftp.FtpClient介绍
  17. soj.1004 I Conduit!
  18. html5绘制变换图形-旋转图形
  19. 81.(cesium之家)cesium修改灰色背景(默认蓝色)
  20. Web of Science如何导出参考文献

热门文章

  1. C++跳过(忽略)指定字符
  2. java - 菱形输出
  3. JAVA增删查改的实现
  4. JavaScript 灯泡暗亮
  5. python继承和多态_Python 简明教程 --- 21,Python 继承与多态
  6. 没有bug队——加贝——Python 57,58
  7. ResNet网络详解与keras实现
  8. 通信技术计算机通信方向专业,江西科技学院2014年招生通信工程(计算机通信方向)专业介绍...
  9. 语言五子棋无ai程序框图_微软多语言预训练模型T-ULRv2登顶XTREME排行榜
  10. python 格式化输出%和format