【问题分析】使用gperftools分析排查内存问题

背景

当程序长时间允许时(压测、服务器程序),就会面临更大的挑战,其中内存泄漏就是一类典型的问题,内存泄漏往往不易发现,导致的现象更是千奇百怪,本文主要介绍如何借助gperftools分析一个模块的内存泄漏

案例代码

#include <iostream>
#include <thread>
#include <cstring>
#include <chrono>

constexpr int kMallocSize = 1024*1024; // 1Mb

void func1() {
    void* p = malloc(kMallocSize);
    memset(p, 1, kMallocSize);
    free(p);
}

void func2() {
    void* p = malloc(kMallocSize);
    memset(p, 1, kMallocSize);
    //free(p);
}

int main() {

std::thread t1([](){
    while(true) {
        func1();
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
});

std::thread t2([](){
    while(true) {
        func2();
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
});

if(t1.joinable()) {
    t1.join();
}

if(t2.joinable()) {
    t2.join();
}

return 0;
}

很简单的一个程序,有两个线程每个1s执行一次任务,这个任务中会创建1M的内存,在线程2的任务中忘记释放了,这样这个程序长时间运行就会产生内存泄漏。
效果:每1s内存增加1M(观察下面top的RES列内容)

mem_leak内存增长

实际情况中,内存泄漏往往会藏在某个角落,很难通过阅读代码发现,特别是现在的项目代码量都很大

使用gperftools分析定位

gperftools介绍及安装

gperftools 是一组性能分析和内存优化工具,集合中最为人们所知的可能是它的 CPU 分析器(Profiler)和堆分析器(Heap Profiler)。下面我将介绍如何使用 gperftools 中的 CPU 分析器来对 C/C++ 程序进行性能分析。
安装 gperftools,你可以根据你所使用的操作系统和包管理器选择不同的方法。以下是在一些常见环境中安装 gperftools 的指南:

在 Ubuntu/Debian 系统上

使用 apt 包管理器安装:

sudo apt update
sudo apt install google-perftools libgoogle-perftools-dev

这将会安装 gperftools 及其开发库,如果你想要链接 CPU 分析器(profiler)到你的应用程序中,通常需要这些开发库。

在 CentOS/RHEL 系统上

使用 yum 包管理器安装:

sudo yum install gperftools gperftools-libs gperftools-devel

或者,如果你在使用新版本的 RHEL/CentOS(例如 RHEL 8 或 CentOS Stream),你可能需要使用 dnf:

sudo dnf install gperftools gperftools-libs gperftools-devel

在 Fedora 系统上

使用 dnf 包管理器安装:

sudo dnf install gperftools gperftools-libs gperftools-devel

在 macOS 上

如果你在 macOS 中,可以使用 Homebrew 来安装 gperftools:

brew install gperftools

从源代码编译安装

如果你的系统上没有预打包的 gperftools 版本,或者你需要一个特定版本的 gperftools,你还可以从源代码编译安装。首先,你需要下载最新版的源代码:

wget https://github.com/gperftools/gperftools/releases/download/gperftools-2.9.1/gperftools-2.9.1.tar.gz
tar -xzf gperftools-2.9.1.tar.gz
cd gperftools-2.9.1

然后编译并安装:

./configure
make
sudo make install

注意,编译 gperftools 可能需要额外的依赖项,如 libunwind、autoconf、automake 和 libtool 等。

使用堆分析器来分析内存分配情况

详细使用方法可以参考github说明文档

  1. 准备
    pprof是否安装成功
[root@yms:/mnt/data/yms/study]pprof --version
pprof (part of gperftools 2.0)

Copyright 1998-2007 Google Inc.

This is BSD licensed software; see the source for copying conditions
and license information.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

tcmalloc.so的位置

[root@yms:/mnt/data/yms/study]find /usr/ -name libtcmalloc.so
/usr/lib/x86_64-linux-gnu/libtcmalloc.so
  1. 启动堆分析器
    设置LD_PELOAD和HEAPPROFILE,然后运行程序
LD_PRELOAD="/usr/lib/x86_64-linux-gnu/libtcmalloc.so" HEAPPROFILE=/tmp/mem_leak ./gperftools_demo/mem_leak

注意LD_PRELOAD是必须的

其他控制配置:

配置作用
LD_PRELOAD指定用于libtcmalloc.so的路径
HEAPPROFILE指定生成heap-profiling文件的路径
HEAP_PROFILE_ALLOCATION_INTERVAL指示heap dump大小,单位Byte,即每次申请达到N Byte后dump一次,default: 1073741824(1Gb)。也可以指定其他参数
HEAP_PROFILE_INUSE_INTERVAL每增加N Byte dump一次。默认值104857600 (100 Mb)
HEAP_PROFILE_TIME_INTERVAL时间间隔,每隔N Seconds dump一次
HEAP_PROFILE_BUFFER_SIZE设置dump出来的heap文件的最大size。(gperftools源代码中无此参数,代码中的buffer默认为1M,经测试1M的情况下会丢弃不少数据,故建议设置100M(104857600B)
HEAPPROFILESIGNAL可设置dump一次heap文件的信号量(尽量挑选没有被使用到的信号量,比如SIGUSR1(10)和SIGUSR2(12))。
  1. 分析堆数据
    使用pprof查看数据分析结果:
    1. 文本方式查看, 可以明确的看出,内存泄漏在func2上
    [root@yms:/mnt/data/yms/study]pprof --text build/gperftools_demo/mem_leak /tmp/mem_leak.0001.heap 
    Using local file build/gperftools_demo/mem_leak.
    Using local file /tmp/mem_leak.0001.heap.
    Total: 100.0 MB
        99.0  99.0%  99.0%     99.0  99.0% func2
         1.0   1.0% 100.0%      1.0   1.0% func1
         0.0   0.0% 100.0%      0.0   0.0% allocate_dtv
         0.0   0.0% 100.0%      0.0   0.0% std::thread::_S_make_state
         0.0   0.0% 100.0%    100.0 100.0% __GI___clone
         0.0   0.0% 100.0%      0.0   0.0% __libc_start_main
         0.0   0.0% 100.0%      0.0   0.0% __pthread_create_2_1
         0.0   0.0% 100.0%      0.0   0.0% _start
         0.0   0.0% 100.0%      0.0   0.0% allocate_stack (inline)
         0.0   0.0% 100.0%      0.0   0.0% main
         0.0   0.0% 100.0%      1.0   1.0% main::{lambda#1}::operator
         0.0   0.0% 100.0%     99.0  99.0% main::{lambda#2}::operator
         0.0   0.0% 100.0%    100.0 100.0% start_thread
         0.0   0.0% 100.0%      1.0   1.0% std::__invoke@27bf
         0.0   0.0% 100.0%     99.0  99.0% std::__invoke@28e5
         0.0   0.0% 100.0%    100.0 100.0% std::__invoke_impl
         0.0   0.0% 100.0%    100.0 100.0% std::error_code::default_error_condition
         0.0   0.0% 100.0%    100.0 100.0% std::thread::_Invoker::_M_invoke
         0.0   0.0% 100.0%    100.0 100.0% std::thread::_Invoker::operator
         0.0   0.0% 100.0%      0.0   0.0% std::thread::_M_start_thread
         0.0   0.0% 100.0%    100.0 100.0% std::thread::_State_impl::_M_run
         0.0   0.0% 100.0%      0.0   0.0% std::thread::thread
    
    1. 转换成pdf
      首先要安装graphviz
    	 sudo apt install graphviz
    
    然后转换成pdf
    [root@yms:/mnt/data/yms/study]pprof --pdf build/gperftools_demo/mem_leak /tmp/mem_leak.0001.heap > mem_leak.pdf
    Using local file build/gperftools_demo/mem_leak.
    Using local file /tmp/mem_leak.0001.heap.
    Dropping nodes with <= 0.5 MB; edges with <= 0.1 abs(MB
    
    打开pdf
    在这里插入图片描述
  2. 转换成网页
pprof --web ./my_program /tmp/my_heap_profile.0001.heap

思考

好的工具,可以事半功倍,要持续学习使用新工具,人类和动物最大的区别就是学会使用了工具

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/890265.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

yum仓库安装rabbitmq

yum仓库安装rabbitmq 1、配置yum仓库 vim /etc/yum.repos.d/rabbitmq.repo # In /etc/yum.repos.d/rabbitmq.repo## ## Zero dependency Erlang ##[rabbitmq_erlang] namerabbitmq_erlang baseurlhttps://packagecloud.io/rabbitmq/erlang/el/7/$basearch repo_gpgcheck1 gpg…

软件工程:需求规格说明书(图书管理系统)

目录 1 导言 1.1 编写目的 1.2 参考资料 2 项目介绍 2.1 项目背景 2.2 项目目标 3 应用环境 3.1 系统运行网络环境 ​编辑 3.2 系统软硬件环境 4 功能模型 4.1 功能角色分析 4.1.1 图书管理员 4.1.2 普通读者 4.1.3 邮件系统 4.2 功能性需求 4.2.1 预定图…

【一步步开发AI运动小程序】二十、AI运动小程序如何适配相机全屏模式?

引言 受小程序camera组件预览和抽帧图像不一致的特性影响&#xff0c;一直未全功能支持全屏模式&#xff0c;详见本系列文件第四节小程序如何抽帧&#xff1b;随着插件在云上赛事、健身锻炼、AI体测、AR互动场景的深入应用&#xff0c;各开发者迫切的希望能在全屏模式下应用&am…

Excel中Ctrl+e的用法

重点&#xff1a;想要使用ctrle&#xff0c;前提是整合或拆分后的结果放置的单元格必须和被提取信息的单元格相邻&#xff0c;且被提取信息的单元格也必须相连。 下图为错误示例 这样则可以使用ctrle 1、信息整合 2、提取信息 3、添加符号 4、信息顺序调换 5、数字提取 crtle还…

Vue3 + Element plus 实现切换el-radio前二次确认

Vue3 Element plus 实现切换el-radio前二次确认 场景&#xff1a;点击切换el-radio之前判断当前内容是否有改变&#xff0c;如有改变弹窗提示切换el-radio将销毁操作&#xff0c;弹窗二次确认是否切换 问题&#xff1a; el-radio 没有提供类似于beforeUpdate这样的钩子去处理这…

手写mybatis之细化XML语句构建器,完善静态SQL解析

前言 1&#xff1a;在流程上&#xff0c;通过 DefaultSqlSession#selectOne 方法调用执行器&#xff0c;并通过预处理语句处理器 PreparedStatementHandler 执行参数设置和结果查询。 2&#xff1a;那么这个流程中我们所处理的参数信息&#xff0c;也就是每个 SQL 执行时&#…

基于yolov10的芒果成熟度检测系统,支持图像、视频和摄像实时检测【pytorch框架、python】

更多目标检测和图像分类识别项目可看我主页其他文章 功能演示&#xff1a; yolov10&#xff0c;芒果成熟度检测系统&#xff0c;支持图像、视频和摄像实时检测【pytorch框架、python】_哔哩哔哩_bilibili &#xff08;一&#xff09;简介 基于yolov10的芒果成熟度检测系统是…

npm install报错一堆sass gyp ERR!

执行npm install &#xff0c;出现一堆gyp含有sass错误的情况下。 解决办法&#xff1a; 首页可能是node版本问题&#xff0c;太高或者太低&#xff0c;也会导致npm install安装错误&#xff08;不会自动生成node_modules文件&#xff09;&#xff0c;本次试验&#xff0c;刚开…

【JavaEE】——初始网络原理

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯 你们的点赞收藏是我前进最大的动力&#xff01;&#xff01; 希望本文内容能够帮助到你&#xff01;&#xff01; 目录 一&#xff1a;局域网 1&#xff1a;概念 二&#xff1a;局域网的连接方式 1&#xff1a;网线直连 …

flask项目框架搭建

目录结构 blueprints python包&#xff0c;蓝图文件&#xff0c;相当于路由组的概念,方便模块化开发 例如auth.py文件 from flask import Blueprint, render_templatebp Blueprint("auth", __name__, url_prefix"/auth")bp.route("/login") d…

空间解析几何3-空间点到线段和平面的距离【附MATLAB代码】

目录 空间中点到线段的距离 空间中点到平面的投影和距离 matlab代码 空间中点到线段的距离 空间中点到平面的投影和距离 matlab代码 function [dis,P2,t] point2Line (A1,B1,C1) %求空间一点到一线段的最短距离 %[dis,P2,Q2]pointSegmentDistance(A,B,C) %A B为线段首末端…

问卷调查毕设计算机毕业设计投票系统SpringBootSSM框架

目录 一、引言‌ ‌二、需求分析‌ 用户角色‌&#xff1a; ‌功能需求‌&#xff1a; ‌非功能需求‌&#xff1a; ‌三、系统设计‌ ‌技术选型‌&#xff1a; ‌数据库设计‌&#xff1a; ‌界面设计‌&#xff1a; ‌四、实现步骤‌ ‌后端实现‌&#xff1a; …

蓝桥杯【物联网】零基础到国奖之路:十八. 扩展模块之光敏和AS312

蓝桥杯【物联网】零基础到国奖之路:十八.扩展模块之光敏和AS312 第一节 硬件解读第二节 CubeMX配置第二节 代码 第一节 硬件解读 光敏和AS312如下图&#xff1a; 光敏电阻接到了扩展模块的5号引脚&#xff0c;5号引脚接了2个电阻&#xff0c;R8和光敏电阻。我们通过ADC读取这…

vue+ElementUI—实现基础后台管理布局(sideBar+header+appMain)(附源码)

后台管理的模板很多&#xff0c;vue本身就提供了完整的vue-template-admin&#xff0c;vue-admin-beautiful等后台管理系统化框架&#xff0c;但是这些框架正是因为成体系而显得繁重。假如你想搭建一个静态的后台管理模板页面和几个单独的菜单页面&#xff0c;直接就上框架是否…

维生素对于生活的重要性

在探索健康奥秘的旅途中&#xff0c;维生素作为人体不可或缺的微量营养素&#xff0c;扮演着至关重要的角色。它们虽不直接提供能量&#xff0c;却是酶促反应、细胞代谢、免疫功能乃至心理健康的基石。今天&#xff0c;让我们一同深入探讨人体所需补充的维生素&#xff0c;这些…

VSCode 使用 EmmyLua 对lua进行调试

时间&#xff1a;2024年10月 其他&#xff1a;win10&#xff0c;EmmyLua v0.8.20 参考&#xff1a;https://blog.csdn.net/ShenHaoDeHao/article/details/140268354 有几个概念搞清楚就好理解了。一般开发中&#xff0c;我们编写的lua文件由宿主程序的来解析、执行&#xff1…

【计算机网络 - 基础问题】每日 3 题(三十九)

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?typeblog &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/fYaBd &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞…

软件设计师(软考学习)

数据库技术 数据库基础知识 1. 数据库中的简单属性、多值属性、复合属性、派生属性简单属性&#xff1a;指不能够再分解成更小部分的属性&#xff0c;通常是数据表中的一个列。例如学生表中的“学号”、“姓名”等均为简单属性。 多值属性&#xff1a;指一个属性可以有多个值…

目标检测——YOLO11算法解读

作者&#xff1a;Ultralytics公司 代码&#xff1a;https://github.com/ultralytics/ultralytics YOLO系列算法解读&#xff1a; YOLOv1通俗易懂版解读、SSD算法解读、YOLOv2算法解读、YOLOv3算法解读、YOLOv4算法解读、YOLOv5算法解读、YOLOR算法解读、YOLOX算法解读、YOLOv6算…

分布式数据库的进度管理:TiDB 备份恢复工具 PiTR 的原理与实践

导读 对于一款企业级数据库产品而言&#xff0c;数据的安全性和可恢复性是至关重要的。PiTR&#xff08;Point in Time Restore&#xff09;作为 TiDB 备份工具的核心功能之一&#xff0c;提供了一种精细的数据恢复能力&#xff0c;允许用户将数据库集群恢复到过去的任意时间点…