温馨提示×

如何排查linux c++内存

小樊
42
2026-09-17 06:27:43
栏目: 编程语言

在 Linux 下排查 C++ 程序内存问题,通常分为几类场景:内存泄漏、内存越界、内存占用高、OOM、性能问题。下面按「工具 + 方法 + 实战思路」系统讲一下。


一、先明确问题类型

问题 典型表现
内存泄漏 进程 RES 持续增长
内存越界 偶发 crash / 数据错乱
内存占用高 启动就大 / 峰值高
OOM 系统 kill 进程
碎片问题 内存没泄漏但 RSS 不降

二、基础排查手段(必会)

1️⃣ 观察内存使用

top

ps -o pid,rss,vsz,comm -p <pid>
  • RSS:实际物理内存
  • VSZ:虚拟内存

实时监控:

watch -n 1 ps -o pid,rss,vsz,comm -p <pid>

2️⃣ /proc 接口

cat /proc/<pid>/status

关注:

  • VmRSS
  • VmSize
  • VmData
cat /proc/<pid>/maps

看内存映射区域(堆、栈、so)


三、内存泄漏排查(最常见)

✅ 方法 1:Valgrind(最权威)

valgrind --tool=memcheck --leak-check=full ./your_program

优点:

  • 精确
  • 能定位代码行

缺点:

  • 非常慢(10~50x)
  • 不适合线上

适合:

  • 本地复现
  • 单元测试

✅ 方法 2:AddressSanitizer(推荐)

编译时加:

-g -fsanitize=address -fno-omit-frame-pointer

运行:

./your_program

优点:

  • 能检测泄漏 + 越界
  • 支持多线程

缺点:

  • 内存开销大(2x)

✅ 方法 3:tcmalloc + heap profiler

export HEAPPROFILE=/tmp/heap
./your_program

工具:

pprof --pdf your_program heap > heap.pdf

适合:

  • 长期运行服务
  • 内存增长分析

✅ 方法 4:jemalloc + jeprof

MALLOC_CONF=prof:true,prof_active:true
jeprof --pdf ./your_program jeprof.* > out.pdf

四、内存越界 / 野指针

✅ AddressSanitizer(强烈推荐)

能检测:

  • 堆溢出
  • 栈溢出
  • use-after-free

示例错误:

ERROR: AddressSanitizer: heap-buffer-overflow

✅ Valgrind(补充)

valgrind --tool=memcheck ./app

✅ GDB(离线分析)

gdb ./app core
bt

五、线上环境怎么做?

✅ 1. 不重启定位(轻量)

pmap -x <pid>
cat /proc/<pid>/smaps

看:

  • 哪个区域大
  • 是否是 heap / anonymous

✅ 2. 定期 dump 堆

使用:

  • tcmalloc heap profiler
  • jemalloc prof

✅ 3. 使用 perf(高级)

perf record -g -p <pid>
perf report

看内存分配热点函数


六、C++ 常见内存问题清单

✅ 必查点:

  • new/delete 不匹配
  • std::vector resize 滥用
  • 全局容器无限 push
  • 智能指针循环引用
  • 缓存未清理
  • 线程局部变量堆积
  • 第三方库内存泄漏

七、推荐组合方案(实战)

本地开发

ASan + UBSan

测试环境

Valgrind

线上服务

tcmalloc / jemalloc + profiler

八、如果你愿意

你可以告诉我:

  • ✅ Linux 发行版
  • ✅ 是服务还是程序
  • ✅ 是否可重启
  • ✅ 是否用 STL / 智能指针
  • ✅ 具体现象(RSS 涨?crash?)

我可以直接给你 可执行的排查步骤或脚本

0