qt内存泄漏检测_独家|Linux进程内存用量分析之堆内存篇

导语

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

背景

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

1.内存泄漏。

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

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

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

常见内存问题的分析方法

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

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

917dc200831844c0650901c2c63772c0.png

AddressSanitizer检测内存泄漏

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

1a4f4ca15fa0a0dc21f91bfcd101c283.png

AddressSanitizer与Valgrind对比

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

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

Valgrind:http://valgrind.org/

而对于后两种原因,我们需要根据不同的分配器区别看待。常见的分配器有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进程如下:

0b1bbe0eca81510706870f83366a5420.png

运行中的realtime_searcher进程

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

2.工具介绍

这里介绍一个非常强大的内存分析工具——core_analyzer。这是一个基于core文件的内存分析工具,由Michael Y

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值