使用valgrind检查内存问题并且输出报告

valgrind基本功能介绍、基础使用方法说明 拷贝效果不好,请看原文。1、Valgrind概述Valgrind是一套Linux下,开放源代码(GPL V2)的仿真调试工具的集合。Valgrind由内核(core)以及基于内核的其他调试工具组成。内核类似于一个框架(framework),它模拟了一个CPU环境,并提供服务给其他工具;而其他工具则类似于插件 (plug-in),利用内核提供的服务完成各种特定的内存调试任务。 阅读详情
AI摘要

本文介绍了如何使用Valgrind工具进行内存泄漏检测,并提供了详细的命令行参数解释。此外,还探讨了如何通过读取/proc/[pid]/statm文件来收集Linux进程的内存数据,以便进一步分析内存使用趋势。

valgrind内存泄漏分析

是在linux中检查内存泄漏的工具。当程序编写完之后我一般都会使用它来检查一次内存问题。基本上能杜绝服务器的内存泄漏问题(当然是面对C/C++这样的语言的)。
使用方式就是将程序编译好,然后通过valgrind来启动程序。当测试完全部的内存测试用例之后,让服务器程序正常退出。在最后结束的时候将会输出服务器的内存泄漏报告。不过valgrind对于protobuf,stl这样的3方库的兼容性不算太好,所以会造成输出一堆的still reachable字样。其实完全没有必要去纠结这些问题。可以肯定这些都是误判的。当你使用了这样的库的情况下,一般都会需要将这些检查option关闭掉。防止自己被爆出来的一堆的错误唬住了。信息太多反而阻碍自己的判断。
下面是一般启动程序使用的指令:

valgrind --log-file=./valgrind_report.log --leak-check=full --show-leak-kinds=all --show-reachable=no --track-origins=yes ./

这个里面使用到的option分别的意义:

–log-file
指定报告输出文件
–track-origins=yes
是否显示未定义的变量,在堆、栈中被定义没有被initialised的变量都被定义成origins。默认是关闭这个option的。
–show-leak-kinds=all
这里可以支持的选项有[definite|possible],一般只需要去关注definite(绝逼),possible是可能会存在。
–leak-check=full
当服务器退出时是否收集输出内存泄漏,选项有[no|summary|full]这个地方我们将其设置成全输出,默认将会使用summary方式。

输出报告之后重点看definite的,而且关于自己程序的。其次再去看possible的内存分配点的释放。

收集linux进程内存数据

对于在linux中的进程内存使用在/proc/[pid]/statm文件中其实是写了进程的内存使用情况。如果我们想去分析一个进程的内存长时间使用的趋势,可以在crontab中写一个定时运行的脚本通过读取这个文件来定时采集服务器的内存使用情况。如果服务器中安装了mysql数据库,可以使用命令行将这些数据入库。然后通过chart.js+php将数据通过图表方式呈现出来。数据收集了之后,其实也是没法子判断出数据的趋势。所以得让数据图形化。

/proc/[pid]/status文件中我们可以抓取服务器的内存相关的信息(单位为bytes):

VmPeak:   393532 kB
VmSize:   393532 kB
VmLck:         0 kB
VmPin:         0 kB
VmHWM:     35012 kB
VmRSS:     35012 kB
VmData:   328460 kB
VmStk:       268 kB
VmExe:      2248 kB
VmLib:     12836 kB
VmPTE:       228 kB
VmSwap:        0 kB

VmPeak = 虚存历史最高值
VmSize = 虚存
VmHWM = 物理内存最高值
VmRSS = 物理内存
VmData, VmStk, VmExe = 数据、栈和文本代码内存
VmLib = 共享库代码内存大小
VmPTE = 全部页表内存大小
VmLck = 锁定内存大小(参考:mlock)
VmSwap = 交换

/proc/[pid]/statm文件中对于内存的描述如下(度量单位是页):
提供某个pid下的内存使用情况。下面是每页的含义:

列编号名称详解
1size全部程序的大小,就是top中的VIRT虚存大小
2resident程序使用的实存,在top中的Res
3share共享页大小
4text文本(代码)
5lib库(Linux2.6无用)
6data数据和堆
7dt脏页大小(Linux 2.6无用)

为了直观理解的方便,我们可以使用bytes方式。
接下来就是将入库之后的内存做出曲线图了。这里需要使用的技术是apache+php+chart.js。
我们只需要编写一个页面来实现这个功能。在web世界里面,php是跑在服务器段的,它负责去在服务器中执行并且获得返回信息。并且通过打印字符串通过apache将这些http的文本发给browse。当browse拿到http文本,如果读取到了js这种前段的脚本,就会根据文本在本地绘画。我们这个示例就是通过php去读取mysql中我们已经收集到的某个服务器的memory的历史使用趋势数据。并且将数据写入到http中,并且填充一个js脚本。

python采集脚本

先请自己去创建一个数据库,然后就是将这个python写成一个crontab的东西吧。如果方便可以在自己的服务器里面部署一套来玩玩。

#! /usr/bin/python
# -*- coding: utf8 -*-
import os,re


#  CREATE TABLE `MEM_LOG` (
#    `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
#    `pid` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '唯一id',
#    `VmPeak` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '虚存历史最高值',
#    `VmSize` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '虚存',
#    `VmHWM` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '物理内存最高值',
#    `VmRSS` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '物理内存',
#    `VmData` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '数据',
#    `VmStk` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '栈',
#    `VmExe` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '文本代码内存',
#    `VmLib` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '共享库代码内存大小',
#    `VmPTE` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '全部页表内存大小',
#    `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '刷新时间',
#    PRIMARY KEY (`id`)
#  ) ENGINE=InnoDB ;

fields = [ 'VmPeak', 'VmSize', 'VmHWM', 'VmRSS', 'VmData', 'VmStk', 'VmExe', 'VmLib', 'VmPTE' ]
def read_pid_memory_info(pid):
    fd = open("/proc/%d/status"%pid,"r")
    record = {}
    record[ 'pid' ] = pid
    for line in fd.readlines():
        for field in fields:
            r = re.compile('%s: * *([0-9]+) kB'%field)
            r_result = r.findall( line )
            if len(r_result) == 0:
                continue
            record[ field ] = int( r_result[0] ) 
            pass
        pass
    fd.close()
    return record

def insert_into_db( record ):
    field_str = ''
    value_str = ''
    for field in record:
        field_str = field_str + ',' + field
        value_str = value_str + ',' + str( record[ field ] )
        pass
    field_str = field_str[1:]
    value_str = value_str[1:]
    sql = 'insert into MEM_LOG ( %s ) VALUES ( %s );'%( field_str, value_str )
    print( sql )
    prompt = 'mysql -uroot -pyourpassword mem_log_db -e "%s"'%(sql)
    os.system( prompt )
    pass

pip = os.popen( "ps aux | grep your_system | grep -v grep | awk '{print $2}'" )
all_proc = []
for line in pip.readlines():
    pid = int( line.replace('\n','') )
    print "pid is: %d"%pid
    record = read_pid_memory_info(pid)
    insert_into_db( record )
    pass

让他每10分钟统计一条出来:

*/10 * * * * /home/sean/memory_spy/spy.py

注意需要将这个spy.py设置成一个可执行的程序。

连接MySQL读取数据


<?
 $mysql_server_name="127.0.0.1"; //数据库服务器名称
    $mysql_username="xxx"; // 连接数据库用户名
    $mysql_password="xxx"; // 连接数据库密码
    $mysql_database="xxx"; // 数据库的名字

    // 连接到数据库
    $conn=mysql_connect($mysql_server_name, $mysql_username,
                        $mysql_password);

     // 从表中提取信息的sql语句
    $strsql="SELECT * FROM `MEM_LOG`";
    // 执行sql查询
    $result=mysql_db_query($mysql_database, $strsql, $conn);
    // 获取查询结果
    $row=mysql_fetch_row($result);



    $labels = array();
    $vm = array();
    $rm = array();
    $lua = array();

    mysql_data_seek($result, 0);
    // 循环取出记录
    while ($row=mysql_fetch_row($result))
    {
        array_push($labels, $row[0]);
        array_push($vm, $row[1]);
        array_push($rm, $row[2]);
        array_push($lua, $row[3]);
    }

    // 释放资源
    mysql_free_result($result);
    // 关闭连接
    mysql_close($conn);  

创建js的画布

注意:这里是下载了一份Chart.js-1.0.2放到了站点的根目录。否则会报错说这个js找不到。

<script src="Chart.js-1.0.2/Chart.js">
</script>
<canvas id="myChart" width="1800" height="400"></canvas>

通过php来填充数据

这个具体的实例,可以去抄一下chart.js的官方的一些实例就能去做饼状图,具状图之类的了。

    echo json_encode($labels);
    echo '<br/>';
    echo '
<script type="text/javascript">
var data = {
            labels: ' . " " .  json_encode($labels) . " " .  ',
            datasets: [
            {
            label: "Vm",
            fillColor: "rgba(220,220,220,0.2)",
            strokeColor: "rgba(220,220,220,1)",
            pointColor: "rgba(220,220,220,1)",
            pointStrokeColor: "#fff",
            pointHighlightFill: "#fff",
            pointHighlightStroke: "rgba(220,220,220,1)",
            data: ' . " " .  json_encode($vm) . " " .  '
            },
            {
            label: "rm",
            fillColor: "rgba(151,187,205,0.2)",
            strokeColor: "rgba(151,187,205,1)",
            pointColor: "rgba(151,187,205,1)",
            pointStrokeColor: "#fff",
            pointHighlightFill: "#fff",
            pointHighlightStroke: "rgba(151,187,205,1)",
            data: ' . " " .  json_encode($rm) . " " . '
            },
            {
            label: "lua",
            fillColor: "rgba(120,120,120,0.2)",
            strokeColor: "rgba(120,120,120,1)",
            pointColor: "rgba(120,120,120,1)",
            pointStrokeColor: "#fff",
            pointHighlightFill: "#fff",
            pointHighlightStroke: "rgba(220,220,220,1)",
            data: ' . " " .  json_encode($lua) . " " .  '
            }
            ]
            };
</script>';

设置图表的option,并且将数据画到画布上


<script type="text/javascript">
var options ={

            ///Boolean - Whether grid lines are shown across the chart
            scaleShowGridLines : true,

            //String - Colour of the grid lines
            scaleGridLineColor : "rgba(0,0,0,.05)",

            //Number - Width of the grid lines
            scaleGridLineWidth : 1,

            //Boolean - Whether to show horizontal lines (except X axis)
            scaleShowHorizontalLines: true,

            //Boolean - Whether to show vertical lines (except Y axis)
            scaleShowVerticalLines: true,

            //Boolean - Whether the line is curved between points
            bezierCurve : true,

            //Number - Tension of the bezier curve between points
            bezierCurveTension : 0.4,

            //Boolean - Whether to show a dot for each point
            pointDot : true,

            //Number - Radius of each point dot in pixels
            pointDotRadius : 4,

            //Number - Pixel width of point dot stroke
            pointDotStrokeWidth : 1,

            //Number - amount extra to add to the radius to cater for hit detection outside the drawn point
            pointHitDetectionRadius : 20,

            //Boolean - Whether to show a stroke for datasets
            datasetStroke : true,

            //Number - Pixel width of dataset stroke
            datasetStrokeWidth : 2,

            //Boolean - Whether to fill the dataset with a colour
            datasetFill : true,


            };


                    var ctx = document.getElementById("myChart").getContext("2d");
var myLineChart = new Chart(ctx).Line(data, options);

</script>

内存使用图

conclusion

最后如果你想将一个服务器的内存吃准了,其实还是来自于平日里对于服务器的把控。如同编制竹篓子,平时下功夫檫亮眼睛去多检查就扎实了。即使崩了也不会一泻千里的坏掉。

内存检查工具valgrind介绍、安装与使用 关于内存泄漏动态检查的工具有很多,其中使用最广泛的可能就是valgrind了。面向应用,valgrind是内存调试(例如排查内存泄漏)十分得力的工具。 阅读详情

相关推荐

valgrind 检查内存泄漏

内存泄漏是coding中经常容易出现的问题, 而且很难查。 本文中总结了几个常见的内存泄漏问题, 分别举例实现, 并列出用代码分析工具——valgrind中memcheck检查的结果, 一 一对错误进行排查。本文围绕工程valgrind-sample进行讲解。 先看下工程结构: methods类写了几个可能存在内存操作问题的函数, main.cpp调用methods类函数: method

Rachel Zhang的专栏 1万+

内存问题分析工具_valgrind之memcheck基本使用

1. 下载安装 下载地址:Valgrind: Current Releases 安装:例如版本 valgrind-3.18.1 tar xvf valgrind-3.18.1.tar.bz2 cd valgrind-3.14.0/ ./configure make sudo make install 2. 使用示例 valgrind --log-file=valgrind.log --tool=memcheck --leak-check=full --show-leak-kinds=all .

惊鸿一博 1975

linux下用valgrind做内存检查

用C/C++开发其中最令人头疼的一个问题就是内存管理,有时候为了查找一个内存泄漏或者一个内存访问越界,需要要花上好几天时间,如果有一款工具能够帮助我们做这件事情就好了,valgrind正好就是这样的一款工具。Valgrind是一款基于模拟linux下的程序调试器和剖析器的软件套件,可以运行于x86, amd64和ppc32架构上。valgrind包含一个核心,它提供一个虚拟的CPU运行程序,还有一

plusboy的专栏 3306

valgrind

-tool= 最常用的选项。--log-file= 将输出的信息写入到filename.PID的文件里,PID是运行程序的进行ID。--log-file-qualifier= 取得环境变量的值来做为输出信息的文件名。--db-command= 启动调试器的命令行选项[gdb -nw %f %p]--log-fd= 输出LOG到描述符文件 [2=stderr]--log-file-exactly= 输出LOG信息到 file。

ddddfang的专栏 677

Linux内存 | valgrind工具检查内存泄漏问题

内存泄漏不知道如何检查的看过来

weixin_44458100的博客 718

C++使用Valgrind 定位内存泄漏

C++使用Valgrind 定位内存泄漏 Valgrind 概述 体系结构 Valgrind是一套Linux下,开放源代码(GPL V2)的仿真调试工具的集合。Valgrind由内核(core)以及基于内核的其他调试工具组成。内核类似于一个框架(framework),它模拟了一个CPU环境,并提供服务给其他工具;而其他工具则类似于插件 (plug-in),利用内核提供的服务完成各种特定的内存调试任...

此心光明,亦复何言~ 1470

valgrind官方手册翻译(一)_20151128

Quick Start Guide快速上手快速上手列表1、简介2、你的程序应当作的准备3、使用memcheck检测你的程序4、memcheck输出含义5、注意事项6、更多信息简介Valgrind系列工具是提供一系列可以使你的程序运行更快更稳定调试、监测工具组。这里面最常用的便是memcheck工具,它能够检测出C和C++程序中的多种致命的内存问题。下面的使用说明主要是教你快速上手memcheck工具

绯浅yousa的笔记 2140

dify工作流的原理

摘要: Dify 工作流是一个基于有向无环图(DAG)的智能任务编排系统,支持多节点(如LLM调用、API工具、条件分支等)的可视化拖拽与流程编排。其核心原理包括执行引擎(解析DAG并管理节点依赖)、上下文变量传递(类Jinja模板的变量引用机制)和状态持久化(存储执行日志与中间结果)。工作流通过事件驱动执行,支持异步任务调度,并与RAG知识库、LLM服务等模块深度集成,最终可发布为API或对话应用。技术栈基于Python(FastAPI+Celery)和PostgreSQL,实现低代码化的AI应用开发。

nbspzs的专栏 2185

valgrind 检测内存泄漏

使用 libtorch 发现有内存泄漏问题 安装与下载 从 这里 下载 wget https://sourceware.org/pub/valgrind/valgrind-3.17.0.tar.bz2 tar -jxvf valgrind-3.17.0.tar.bz2 cd valgrind-3.17.0 mkdir _build cd _build ../configure --prefix="xxxx" #[可选] make -j make install 使用 假设你有个要检查的程序为 vtts_t

长虹剑的专栏 1587

力软敏捷开发框架源码7.0.6旗舰版 JNPF开发平台3.4.5 企业版 旗舰版

JNPF作为作为一款深受用户喜爱的低代码产品,凭借雄厚的科研技术力量、丰富的软件开发项目经验、严谨的项目开发流程和高质量的售后服务,已成功帮助千家企业完成数字化项目,建立了覆盖不同行业客户和不同发展阶段的软件产品服务体系。

huoooos0的博客 1839

深入解析6T SRAM的读写机制与性能优化

本文深入解析了6T SRAM的基本结构与核心工作原理,详细阐述了其读写操作的具体时序与机制。文章重点探讨了在先进工艺下面临的读写稳定性、写入能力等性能挑战,并系统介绍了写入辅助与读取辅助等关键优化技术,旨在提升SRAM的可靠性与整体性能。

weixin_29205061的博客 1224

使用valgrind来检查内存泄漏

之前写代码,有少量的内存泄露,平时没发现,长时间运行才发现问题。为以后更方便的检测内存泄漏问题,于是学习使用了valgrind来对内存泄漏进行检测。valgrind不止可以检测内存泄露,但目前只使用这一功能。1.安装去以下链接下载安装文件下载链接 下载完成后解压,终端进入解压后的文件夹,依次输入./configure make make install如遇提示权限不够,make前加sudo 如果

搬砖笔记 1万+

S7-200SMART系列全套接线说明

SMART200接线方法,输入,输出,模拟量,面板,扩展糟等,并且详细说明接线原理。

文都龙哥 1万+

如何使用Valgrind来检测内存泄漏和其他内存问题

Valgrind将运行你的应用程序,并输出内存泄漏的详细报告到终端。报告中包括泄漏的内存块、泄漏的大小、以及可能导致泄漏的代码位置。:查看“LEAK SUMMARY”部分,找出“definitely lost”或其他错误信息的具体记录。选项指示Valgrind进行详细的内存泄漏检查。:追踪未初始化内存的来源,帮助识别问题的根源。使用Qt的父子对象机制自动管理内存。为你的Qt应用程序的可执行文件路径。确保在容器中删除不再需要的对象。:显示仍然可达的内存块。分配的内存都有对应的。

Xue6173的博客 1602

2026年数学建模国赛B题无线电干扰源的快速自动定位与清除 论文详细解析

数学建模竞赛论文无线电干扰源的快速自动定位与清除2026 年高教社杯全国大学生数学建模竞赛 B 题完整求解论文交会定位、极大极小测点优化、自适应多频道搜索与定向源恢复的统一建模模型、算法、代码、图表与验证一体化交付本文研究圆形目标区域中多个未知无线电干扰源的快速检测、定位与清除问题,建立了由误差楔交会模型、角度观测信息模型、分层勘测模型、鲁棒射线交会模型和定向覆盖反馈模型组成的统一求解框架。模型同时覆盖题目中的四个子问题:多测向射线形成的多边形定位区域及直径、第二个测点的极大极小优选、全向源自动搜索清除策略

YOLO 356

Spring Boot Jar包加密实战:用ClassFinal与Jasypt打造代码安全堡垒

Spring Boot代码加密与配置保护方案 针对Spring Boot项目源码和配置易被反编译的风险,本文提出ClassFinal字节码加密+Jasypt配置加密的组合方案。ClassFinal通过Maven插件对核心代码加密,运行时需JavaAgent加载,反编译后仅保留空方法体;Jasypt则采用强加密算法保护敏感配置。方案优势包括: 双重保护:ClassFinal加密业务逻辑,Jasypt加密数据库密码等配置 灵活部署:支持密码启动、机器绑定等安全策略 平滑集成:兼容Spring生态,动态解密结合配

墨夶的博客 1092

C/C++内存泄露检查利器—valgrind

Valgrind是一套Linux下,开放源代码(GPL V2)的仿真调试工具的集合。Valgrind由内核(core)以及基于内核的其他调试工具组成。内核类似于一个框架(framework),它模拟了一个CPU环境,并提供服务给其他工具;而其他工具则类似于插件 (plug-in),利用内核提供的服务完成各种特定的内存调试任务。Memcheck。

Linuxer_Martin 3618

SAP_MM模块通过CC11 创建物料版本

通过本文,我们了解了 SAP 的[SAP_MM模块通过CC11 创建物料版本]的基本概念和应用方法。当物料主数据、BOM(物料清单)、工艺路线等对象需要进行变更控制时,通过创建“版本”或“更改单”来记录、控制和追溯变更。创建完变更主记录(Change Number)后,可在物料主数据维护时引用它,从而创建物料版本化信息。,在其中可以定义物料、BOM、工艺路线等对象的变更版本信息,从而在系统中实现版本化的物料管理。

我小时候很黑的博客 814

valgrind进行内存检查的简单使用

主要内容:1、valgrind简介 2、一些参数信息 3、valgrind安装 4、valgrind简单使用

qq_49354204的博客 1064

Dify智能体开发:发布嵌入网站

Dify 支持将你的 AI 应用嵌入到业务网站中,你可以使用该能力在几分钟内制作具有业务数据的官网 AI 客服、业务知识问答等应用。点击 WebApp 卡片上的嵌入按钮,复制嵌入代码,粘贴到你网站的目标位置。

王国平的博客 3243

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

使用Valgrind解决内存问题

使用Valgrind解决内存问题

小x的博客 881

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

使用valgrind工具检查内存泄漏

讲解Linux下使用valgrind工具对c/c++程序进行内存泄漏检测的方法。

小爱玄策 1647

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

【开发工具】【Valgrind】内存问题检测工具(valgrind)的使用

Valgrind是一套Linux下,开放源代码(GPL V2)的仿真调试工具的集合。 Valgrind由内核(core)以及基于内核的其他调试工具组成。 内核类似于一个框架(framework),它模拟了一个CPU环境,并提供服务给其他工具; 而其他工具则类似于插件 (plug-in),利用内核提供的服务完成各种特定的内存调试任务。

诸葛一帆丶的博客 2912

valgrind检查内存泄露

c++没有垃圾回收机制,程序往往会出现内存泄露,即从堆上获取资源(malloc/new)、用完后没有返回(free/delete)给系统。 valgrind是一个检测内存泄露的工具。 安装 sudo apt-get install valgrind 使用 写一个产生内存泄露的代码,名为leak1.cpp //leak1.cpp #include <cstdlib> using nam...

FANG的博客 3029
上一篇: System V共享内存函数基础
下一篇: strace统计程序系统调用
erlang_hell
博客等级 码龄14年 57粉丝 89原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值