tddms master 服务的内存信息收集

  其他常见问题
内容纲要

概要描述

tddms 是由 C++ 和 Raft 架构实现的高性能分布式数据库项目,如果要收集这类产品的堆栈信息,需要掌握一些 C++ 内存排查命令。

详细说明

  1. top
  2. 通过 smaps 文件查看进程的内存段
  3. pmap
  4. gdb 调试模式
  5. gcore 收集堆内存快照
1. 确认内存占用的实际情况

首先执行 TOP ,确认是 RSS (常驻内存) 高,还是 VIRT (虚拟内存) 高。C++ 程序使用 TCMalloc 时,VIRT 通常会非常大(预分配),这通常是正常的;我们需要关注的是 RSS。

file

2. 查看进程的内存段

查看 /proc/1/smaps 文件中的内存段,可以使用 cat 结合 awk 统计占用了最多 RSS 的内存段。
或者是将这个 smaps 文件拿出来,我们来分析一下。

file

3. 使用 pmap 命令分析内存占用

pmap 是直接解析 smaps 中文件的内容,生成格式化的消息或者摘要、统计信息等。

# -x: 显示扩展信息(包括 RSS、脏页等),这是必须的。
pmap -x 1

# 只看统计摘要(快速判断)
pmap -q 1

# -XX: 显示最详细信息,包括内存权限、偏移量、具体的映射路径(这对识别 RocksDB 的 SST 文件至关重要)。
pmap -XX 1 | less

我们根据 pmap -XX 1 | less 的结果为例,做个介绍。

file

mapping 列为对象名
size 列是理论占用的内存大小
Rss 列是占用的物理内存大小

这里有几种情况:
1、如果 mapping 列有很多的 anon,可能是 block cache 可能是正常的。
2、如果 mapping 列出现了 sst 文件说明加载了很多文件。
3、如果 mapping 列出现了很多 stack 说明并发很高。

4. gdb 命令的使用

参考 gdb 命令的使用。
GDB (GNU Debugger) 是一个功能强大的源代码级调试器,主要用于调试用 C、C++、Ada、Objective-C、Assembly 等编译型语言编写的程序。

这里举个例子:

# 触发一次强制释放内存
sudo gdb -q -batch -ex 'call malloc_trim(0)' -ex detach -ex quit -p 
  • -q: Quiet模式。不打印 GDB 的启动版权信息和欢迎语,让输出更干净。
  • -batch: 批处理模式。GDB 执行完所有命令后自动退出,不会进入交互界面。
  • -ex ‘command’: Execute。执行紧随其后的 GDB 命令。可以多次使用。
    • -ex ‘call malloc_trim(0)’: 核心动作。调用 C 标准库函数 malloc_trim。
    • -ex detach: 执行完后从进程分离,让进程恢复运行。
    • -ex quit: 退出 GDB 程序本身。
  • -p : 指定要附加的目标进程 ID。
# 抓取全量线程堆栈(排查死锁/CPU负载)
gdb -ex "set pagination 0" -ex "thread apply all bt" -batch -p 1 > /tmp/gdb2.txt
  • -ex "set pagination 0": 关闭分页。默认 GDB 输出长时会暂停(显示 –More–),这在脚本中会卡死。关闭后一次性输出所有内容。
  • -ex "thread apply all bt": 核心动作。
    • thread apply all: 对所有线程执行后续命令。
    • bt: Backtrace。打印当前线程的函数调用堆栈。
    • 合起来:打印进程中每一个线程此刻正在执行的代码路径。
  • -batch: 执行完自动退出。
  • -p 1: 附加到 PID 为 1 的进程(请替换为实际 PID)。
  • /tmp/gdb2.txt: 将输出重定向保存到文件,方便后续分析。

功能非常类似于 阿里的 Arthas (开源的 Java 诊断工具)

它的核心作用是让开发者能够:

  • 控制程序执行:设置断点(breakpoints)、单步执行(step/next)、继续运行(continue)。
  • 检查状态:查看变量值、寄存器内容、内存数据、调用栈(backtrace)。
  • 分析崩溃:当程序段错误(Segmentation Fault)或崩溃时,分析核心转储文件(core dump)以定位问题根源。
  • 动态修改:在运行时修改变量值或甚至修改指令(高级用法)。

在 C/C++ 领域,尤其是在 Linux 服务器环境下排查崩溃(Core Dump)、段错误或复杂的内存问题时,gdb 仍然是不可替代的首选工具,即使是使用 IDE(如 VS Code, CLion),底层往往也是调用的 GDB。

5. 收集堆内存快照

原理:瞬间“冻住”进程并保存内存快照到磁盘(Core 文件),然后 GDB 去分析这个文件,原进程可立即恢复(或重启)。

# 定义生成的文件名字
echo "/tmp/core.%e.%p" > /proc/sys/kernel/core_pattern

# 生成 Core 文件(使用 gcore 工具,比 kill 更温和)
sudo gcore 1

# 这会生成 /tmp/core.master_main.1,进程只会暂停几秒钟

这篇文章对您有帮助吗?

平均评分 0 / 5. 次数: 0

尚无评价,您可以第一个评哦!

非常抱歉,这篇文章对您没有帮助.

烦请您告诉我们您的建议与意见,以便我们改进,谢谢您。