Linux 性能实战系列 - 附录 Valgrind介绍

Valgrind 是一个 动态二进制分析框架 ,本身像一个"平台",在它之上运行不同的 分析工具(tools)

其中最常用的三个工具就是:

  • Memcheck
  • Callgrind
  • Massif

它们的关系可以理解为:

复制代码
                Valgrind (框架)
                      │
     ┌────────────────┼────────────────┐
     │                │                │
  Memcheck         Callgrind         Massif
 (内存正确性)      (CPU性能分析)     (堆内存分析)

三者目标完全不同,只是运行在同一个框架上。


一、Memcheck:内存错误检测工具

Memcheck 是 Valgrind 最常用的工具 ,主要用于发现 内存使用错误

能检测的问题

1️⃣ 内存泄漏

复制代码
definitely lost: 1024 bytes

例如:

c 复制代码
char *p = malloc(100);

没有 free(p)


2️⃣ 未初始化内存使用

c 复制代码
int x;
printf("%d\n", x);

Memcheck 会报告:

复制代码
Conditional jump or move depends on uninitialised value

3️⃣ 越界访问

c 复制代码
int a[10];
a[10] = 5;

报告:

复制代码
Invalid write of size 4

4️⃣ Use-after-free

c 复制代码
free(p);
*p = 1;

原理(简化)

Memcheck 为程序维护两种 shadow memory:

复制代码
真实内存
   │
   ▼
shadow memory
 ├── addressability (是否可访问)
 └── definedness   (是否初始化)

每条指令都会被 动态插桩(instrumentation) 检查。


运行方式

bash 复制代码
valgrind --tool=memcheck ./app

二、Callgrind:CPU性能分析工具

Callgrind 用于 分析程序执行时 CPU 时间消耗在哪里

它记录:

  • 函数调用关系
  • 每个函数执行的指令数
  • 调用图

输出文件:

复制代码
callgrind.out.<pid>

可用工具可视化:

  • KCachegrind
  • QCachegrind

示例

bash 复制代码
valgrind --tool=callgrind ./app

结果:

复制代码
Function                 Instructions
--------------------------------------
main                     10,000
foo                      6,000
bar                      3,000

可视化调用关系:

复制代码
main
 ├── foo
 │     └── baz
 └── bar

特点

Callgrind 不测真实时间,而是统计:

复制代码
CPU instructions

所以适合:

  • 算法性能分析
  • 热点函数定位

三、Massif:堆内存使用分析

Massif 用于分析:

程序在运行过程中堆内存是如何增长的

也就是 memory profile


运行

bash 复制代码
valgrind --tool=massif ./app

输出:

复制代码
massif.out.<pid>

分析:

bash 复制代码
ms_print massif.out.<pid>

示例输出

复制代码
Heap usage

    MB
10.0|        ######
    |       #      #
 5.0|      #        #
    |     #          #
 0.0+----+----+----+---->
      t1   t2   t3   t4

表示:

复制代码
时间  → 内存变化

Massif 会告诉你

复制代码
Peak heap: 120MB

90MB allocated at:
   foo()
   bar()
   main()

也就是:

哪一段代码造成了最大内存占用


四、三者核心区别

工具 作用 分析对象 典型用途
Memcheck 内存错误检测 内存访问 查内存泄漏
Callgrind CPU性能分析 指令执行 找热点函数
Massif 堆内存分析 内存占用 分析内存增长

五、三者运行开销对比

Valgrind 最大问题是

工具 速度
Memcheck 20--50x 慢
Callgrind 10--30x 慢
Massif 5--20x 慢

原因:

Valgrind 会:

复制代码
CPU指令
 ↓
Valgrind IR
 ↓
插桩
 ↓
执行

属于 动态二进制翻译 (DBI)


六、一个完整调试流程(真实开发常见)

一个 C/C++ 项目常见的 Valgrind 使用流程:

第一步:找内存问题

复制代码
valgrind --tool=memcheck

解决:

  • memory leak
  • invalid read/write

第二步:分析性能热点

复制代码
valgrind --tool=callgrind

定位:

复制代码
最慢函数

第三步:分析内存峰值

复制代码
valgrind --tool=massif

定位:

复制代码
内存增长来源

七、三者在 Valgrind 内部的关系(架构)

Valgrind 架构:

复制代码
                Program
                   │
                   ▼
           Valgrind Core
     (Dynamic Binary Translation)
                   │
        ┌──────────┼──────────┐
        │          │          │
     Memcheck   Callgrind   Massif
   (memory)     (cpu)       (heap)

核心部分:

复制代码
VEX IR

所有工具都基于这个 IR 插桩。


八、一个很多人不知道的事实

很多人以为:

复制代码
Memcheck 可以分析内存占用

其实 不行

Memcheck 只做:

复制代码
memory correctness

而不是:

复制代码
memory profiling

所以:

需求 工具
查内存泄漏 Memcheck
查内存占用 Massif

九、一个非常实用的工具组合

Linux 内存分析常见组合:

工具 用途
Valgrind Memcheck 查错误
Valgrind Massif 查内存
perf 查 CPU
heaptrack 高级 heap profiler

其中:

Heaptrack

实际上是 Massif 的现代替代品

相关推荐
主角1 72 小时前
Nginx安全
linux·运维·nginx
wanhengidc2 小时前
服务器被攻击该怎么办
运维·服务器·网络·安全·游戏·智能手机
繁华如雪亦如歌2 小时前
Linux常用指令简介与速查
linux
TG_yunshuguoji2 小时前
阿里云代理商:阿里云部署OpenClaw 一键更新升级指南
服务器·人工智能·阿里云·云计算
掘根2 小时前
【即时通讯项目】环境搭建8——RabbitMQ,AMQP-CPP
linux·分布式·rabbitmq
gaize12132 小时前
腾讯云内存型服务器|数据库缓存适用
服务器·数据库·腾讯云
白狐_7983 小时前
硬核实战:从零构建飞书 × OpenClaw 自动化情报站(五)
运维·自动化·飞书
va学弟11 小时前
Java 网络通信编程(6):视频通话
java·服务器·网络·音视频
幸福指北12 小时前
我用 Tauri + Vue 3 + Rust 开发了这款跨平台网络连接查看工具PortView,性能炸裂!
运维·网络·监控