滨州做网站的公司,移动端和pc网站,网站建设海报,wordpress网址修改本文将介绍几种内存泄漏检测工具#xff0c;并通过实际例子介绍一种分析堆内存占用量的工具和方法#xff0c;帮助定位内存膨胀问题。背景进程的内存管理是每一个开发者必须要考虑的问题#xff0c;对于C程序进程来说#xff0c;出现问题很多情况下都与内存挂钩。进程崩溃问…本文将介绍几种内存泄漏检测工具并通过实际例子介绍一种分析堆内存占用量的工具和方法帮助定位内存膨胀问题。背景进程的内存管理是每一个开发者必须要考虑的问题对于C程序进程来说出现问题很多情况下都与内存挂钩。进程崩溃问题通常可以使用gdb等调试工具轻松排查并解决。而对于进程内存膨胀这类问题原因通常有三个1.内存泄漏。2.分配器管理的空闲内存较多而造成的内存空洞。3.有未统计使用的未知内存占用。内存泄漏问题可以使用一些工具来检测。但是对于后两种问题却一直没有比较通用的方法去确定。本文将介绍几种内存泄漏检测工具并通过实际例子介绍一种分析堆内存占用量的工具和方法帮助定位内存膨胀问题。常见内存问题的分析方法对于内存泄露问题目前已经有较成熟的工具进行检测这里简单介绍两个工具AddressSanitizer和Valgrind。AddressSanitizer是google开源项目可以用来检测内存泄漏和其他导致进程崩溃的内存问题。它的优势在于造成的额外CPU占用很小但是需要重新编译项目并且在编译的时候添加-fsanitizeaddress选项。在程序运行时如果有任何内存问题就会终止进程并且打印出详细的错误信息。如果进程存在内存泄漏会在进程结束后打印出所有泄漏的内存大小和申请这块内存的调用栈如下图所示AddressSanitizer检测内存泄漏另一个工具Valgrind的优势在于不需要重新编译只需要在运行时加上valgrind --leak-checkyes即可。但是它的额外CPU开销会更大大约是AddressSanitizer的十倍功能上也不及AddressSanitizer完善。下表是两种工具功能和性能的比较AddressSanitizer与Valgrind对比这两种工具不光能够检测内存泄漏对于堆栈溢出等问题也有比较好的效果。对于这两个工具更具体的介绍可以参照官方的使用文档AddressSanitizerhttps://github.com/google/sanitizers/wiki/AddressSanitizerValgrind而对于后两种原因我们需要根据不同的分配器区别看待。常见的分配器有glibc默认的ptmallocgoogle维护的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.32.42.52.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] 退出