Linux 进程资源占用分析指南 - 指南

Linux 进程资源占用分析指南

本文档介绍在 Linux 系统下如何分析和监控进程的资源占用情况,包括 CPU、内存、I/O 等关键指标的查看方法。

目录

快速开始

前提条件

  • 已知进程 ID (PID)
  • 获取 PID 的方法:
    # 通过进程名查找
    pgrep process_name
    ps aux | grep process_name
    # 通过端口查找
    lsof -i :port
    netstat -tlnp | grep :port

命令行工具

1. top 命令(实时监控)

基本用法:

top -p PID

交互式操作:

  • 1 - 显示每个 CPU 核心的使用情况
  • c - 切换显示完整命令行
  • M - 按内存使用排序
  • P - 按 CPU 使用排序
  • f - 添加或删除显示的字段
  • q - 退出

输出说明:

  • %CPU - CPU 使用百分比
  • %MEM - 内存使用百分比
  • VIRT - 虚拟内存大小
  • RES - 物理内存使用(RSS)
  • SHR - 共享内存

2. htop(增强版 top,推荐)

基本用法:

htop -p PID

功能特点:

  • 更直观的彩色界面
  • 树状视图显示进程关系(按 F5
  • 可直接查看进程打开的文件(按 F2 添加列)
  • 支持鼠标操作
  • 实时显示 CPU 和内存使用率

快捷键:

  • F2 - 设置
  • F5 - 树状视图
  • F6 - 排序选择
  • F9 - 发送信号
  • F10 - 退出

3. ps 命令(快照查看)

基本资源查看:

ps -p PID -o pid,ppid,%cpu,%mem,vsz,rss,cmd

详细资源报告:

ps -p PID -o user,pid,ppid,ni,%cpu,%mem,vsz,rss,tty,stat,start,time,cmd,etime

字段说明:

  • pid - 进程 ID
  • ppid - 父进程 ID
  • %cpu - CPU 使用百分比
  • %mem - 内存使用百分比
  • vsz - 虚拟内存大小(KB)
  • rss - 物理内存使用(KB)
  • cmd - 完整命令行
  • etime - 进程运行时间
  • stat - 进程状态

连续监控:

watch -n 1 'ps -p PID -o pid,%cpu,%mem,vsz,rss,cmd'

4. pidstat(详细资源统计)

安装:

# Ubuntu/Debian
sudo apt-get install sysstat
# CentOS/RHEL
sudo yum install sysstat

基本用法:

# 每2秒刷新一次,共显示5次
pidstat -p PID 2 5

详细资源监控:

# 磁盘 I/O 统计
pidstat -d -p PID
# 内存页错误统计
pidstat -r -p PID
# 栈使用统计
pidstat -s -p PID
# 线程级统计
pidstat -t -p PID
# 综合统计(CPU、内存、I/O)
pidstat -u -r -d -p PID 2 5

输出指标:

  • %usr - 用户态 CPU 使用率
  • %system - 内核态 CPU 使用率
  • %guest - 虚拟化 CPU 使用率
  • %CPU - 总 CPU 使用率
  • minflt/s - 次要页错误率
  • majflt/s - 主要页错误率
  • VSZ - 虚拟内存大小
  • RSS - 物理内存使用
  • kB_rd/s - 读取速率(KB/s)
  • kB_wr/s - 写入速率(KB/s)

5. atop(高级监控)

安装:

# Ubuntu/Debian
sudo apt-get install atop
# CentOS/RHEL
sudo yum install atop

基本用法:

atop -p PID

功能亮点:

  • 显示磁盘负载详情
  • 网络带宽使用统计
  • 进程级 GPU 使用(需插件支持)
  • 历史资源记录(按 t 切换时间点)
  • 支持记录和回放

快捷键:

  • t - 切换时间点
  • m - 显示内存信息
  • d - 显示磁盘信息
  • n - 显示网络信息
  • q - 退出

6. nmon(可视化监控)

安装:

# Ubuntu/Debian
sudo apt-get install nmon
# CentOS/RHEL
sudo yum install nmon

基本用法:

nmon -p PID

交互式界面:

  • c - 查看 CPU 使用情况
  • m - 查看内存使用情况
  • d - 查看磁盘 I/O
  • n - 查看网络统计
  • t - 查看进程/线程统计
  • q - 退出

7. iotop(I/O 监控)

安装:

# Ubuntu/Debian
sudo apt-get install iotop
# CentOS/RHEL
sudo yum install iotop

基本用法:

# 实时监控指定进程的 I/O
iotop -p PID
# 显示累计 I/O
iotop -a -p PID

输出说明:

  • DISK READ - 磁盘读取速率
  • DISK WRITE - 磁盘写入速率
  • SWAPIN - 交换分区使用率
  • IO - I/O 使用百分比

8. lsof(列出打开文件)

基本用法:

# 查看进程打开的所有文件
lsof -p PID
# 查看进程打开的网络连接
lsof -p PID -i
# 查看进程打开的文件描述符数量
lsof -p PID | wc -l
# 查看进程打开的具体文件类型
lsof -p PID | grep -E 'REG|DIR|CHR|FIFO|SOCK'
# 查看进程的端口占用
lsof -p PID -iTCP -sTCP:LISTEN
# 查看进程的工作目录
lsof -p PID | grep cwd
# 查看进程打开的文件并按类型统计
lsof -p PID | awk '{print $5}' | sort | uniq -c

字段说明:

  • COMMAND - 命令名
  • PID - 进程 ID
  • USER - 用户
  • FD - 文件描述符
  • TYPE - 文件类型(REG=普通文件, DIR=目录, CHR=字符设备等)
  • DEVICE - 设备号
  • SIZE/OFF - 文件大小或偏移量
  • NODE - inode 号
  • NAME - 文件路径

9. sar(系统活动报告)

安装:

# Ubuntu/Debian
sudo apt-get install sysstat
# CentOS/RHEL
sudo yum install sysstat

基本用法:

# 查看当前 CPU 使用(每1秒刷新,共5次)
sar -u 1 5
# 查看内存使用
sar -r 1 5
# 查看 I/O 统计
sar -b 1 5
# 查看进程相关统计
sar -x PID 1 5
# 查看历史数据(需要启用 sysstat 数据收集)
sar -u
sar -r
sar -b
# 生成综合报告
sar -A > sar_report.txt

优势:

  • 可以查看历史性能数据
  • 适合长期监控和趋势分析
  • 数据可以保存和回放

10. vmstat(虚拟内存统计)

基本用法:

# 每2秒刷新一次,共显示5次
vmstat 2 5
# 查看进程相关统计
vmstat -p /dev/sda1 2 5
# 显示详细的内存统计
vmstat -s

输出说明:

  • procs - 进程统计(r=运行队列, b=阻塞)
  • memory - 内存统计(swpd=交换分区, free=空闲内存)
  • swap - 交换分区使用
  • io - I/O 统计(bi=块读取, bo=块写入)
  • system - 系统统计(in=中断, cs=上下文切换)
  • cpu - CPU 使用百分比

11. pmap(内存映射查看)

基本用法:

# 查看进程的内存映射
pmap -x PID
# 显示详细信息
pmap -XX PID
# 显示设备格式
pmap -d PID
# 显示扩展格式
pmap -X PID
# 查看内存映射摘要
pmap -q PID

输出说明:

  • Address - 内存地址范围
  • Kbytes - 内存大小(KB)
  • RSS - 实际物理内存(KB)
  • Dirty - 脏页大小(KB)
  • Mode - 内存权限(r=读, w=写, x=执行, s=共享, p=私有)
  • Mapping - 映射的文件或设备

用途:

  • 分析内存占用分布
  • 查找内存泄漏
  • 查看共享库占用

12. smem(内存使用统计)

安装:

# Ubuntu/Debian
sudo apt-get install smem
# CentOS/RHEL
sudo yum install smem

基本用法:

# 查看进程内存使用(按 PSS 排序)
smem -P process_name
# 查看指定 PID 的内存使用
smem -p PID
# 显示详细统计
smem -t -k -p PID
# 按用户统计
smem -u
# 生成报告
smem -t -k -P process_name -c "pid user command pss rss"

优势:

  • PSS (Proportional Set Size): 更准确的内存统计,考虑了共享内存
  • USS (Unique Set Size): 进程独占的内存
  • RSS (Resident Set Size): 实际物理内存

13. ss(现代网络连接工具)

基本用法:

# 查看进程的网络连接
ss -tulpn | grep PID
# 查看 TCP 连接
ss -tpn | grep PID
# 查看 UDP 连接
ss -upn | grep PID
# 显示详细信息
ss -tulnap | grep PID
# 查看监听端口
ss -tlnp | grep PID
# 统计连接数
ss -s

相比 netstat 的优势:

  • 更快速
  • 显示更多信息
  • 更好的过滤选项

14. time 命令(执行时间统计)

基本用法:

# 使用 time 命令运行程序并统计资源
time command
# 使用 /usr/bin/time 获取更详细信息
/usr/bin/time -v command
# 查看进程运行时间
time -p sleep 5
# 详细资源统计
/usr/bin/time -f "%E real, %U user, %S sys, %M KB memory" command

输出说明:

  • real - 实际运行时间(墙钟时间)
  • user - 用户态 CPU 时间
  • sys - 内核态 CPU 时间
  • %M - 最大内存使用(KB)

15. taskset / numactl(CPU 亲和性和 NUMA)

基本用法:

# 查看进程的 CPU 亲和性
taskset -p PID
# 查看进程的 NUMA 节点
numactl --show
# 查看进程的 NUMA 统计
numastat -p PID
# 查看系统 NUMA 信息
numactl --hardware

用途:

  • 优化进程的 CPU 绑定
  • 在 NUMA 系统上优化内存访问
  • 提高缓存命中率

16. prlimit(资源限制查看)

基本用法:

# 查看进程的资源限制
prlimit --pid=PID
# 查看特定资源限制
prlimit --pid=PID --as    # 虚拟内存限制
prlimit --pid=PID --rss   # 物理内存限制
prlimit --pid=PID --nofile # 文件描述符限制
prlimit --pid=PID --cpu   # CPU 时间限制

常用资源限制:

  • AS - 虚拟内存大小
  • RSS - 物理内存大小
  • NOFILE - 文件描述符数量
  • CPU - CPU 时间(秒)
  • NPROC - 进程数限制

17. systemd-cgtop(systemd 进程组监控)

基本用法:

# 查看 systemd 管理的进程组资源使用
systemd-cgtop
# 查看特定服务的资源使用
systemd-cgtop /system.slice/service-name.service
# 查看用户服务的资源使用
systemd-cgtop /user.slice/user-1000.slice

适用场景:

  • 监控 systemd 管理的服务
  • 查看容器资源使用(如果使用 systemd-nspawn)
  • 分析服务资源消耗

18. slabtop(内核 slab 缓存监控)

基本用法:

# 实时查看内核 slab 缓存使用
slabtop
# 按使用量排序
slabtop -s c
# 只显示正在使用的缓存
slabtop -o

用途:

  • 诊断内核内存泄漏
  • 查看内核缓存使用情况
  • 分析系统内存压力

系统文件分析

/proc 文件系统(底层信息)

/proc/PID/ 目录提供了进程的详细底层信息。

CPU 使用情况
# 查看进程 CPU 时间统计
cat /proc/PID/stat | awk '{print "用户态CPU: " $14 " 时钟周期"; print "内核态CPU: " $15 " 时钟周期"}'
# 实时监控 CPU 使用率
while true; do
cat /proc/PID/stat | awk '{utime=$14; stime=$15; total=$14+$15; print "用户态: " utime " 内核态: " stime " 总计: " total}'
sleep 1
done
内存使用情况
# 查看内存详细信息
cat /proc/PID/status | grep -E 'VmPeak|VmSize|VmRSS|VmSwap|VmHWM|VmData|VmStk|VmExe'
# 字段说明:
# VmPeak  - 虚拟内存峰值(KB)
# VmSize  - 当前虚拟内存大小(KB)
# VmRSS   - 实际物理内存使用(KB)
# VmSwap  - 交换分区使用(KB)
# VmHWM   - 物理内存峰值(KB)
# VmData  - 数据段大小(KB)
# VmStk   - 栈大小(KB)
# VmExe   - 可执行文件大小(KB)
打开文件描述符
# 查看打开的文件描述符数量
ls -l /proc/PID/fd | wc -l
# 查看具体打开的文件
ls -l /proc/PID/fd
# 查看打开的文件列表(带路径)
for fd in /proc/PID/fd/*; do
readlink -f "$fd"
done
I/O 统计
# 查看 I/O 统计信息
cat /proc/PID/io
# 输出字段说明:
# rchar        - 读取字符数(包括缓存)
# wchar        - 写入字符数(包括缓存)
# syscr        - 系统调用读取次数
# syscw        - 系统调用写入次数
# read_bytes   - 实际磁盘读取字节数
# write_bytes  - 实际磁盘写入字节数
# cancelled_write_bytes - 取消的写入字节数
线程信息
# 查看线程数量
ls /proc/PID/task | wc -l
# 查看每个线程的详细信息
for tid in /proc/PID/task/*; do
echo "线程 ID: $(basename $tid)"
cat $tid/stat | awk '{print "CPU时间: " $14+$15}'
done
上下文切换
# 查看上下文切换统计
cat /proc/PID/status | grep -E 'voluntary_ctxt_switches|nonvoluntary_ctxt_switches'
# 字段说明:
# voluntary_ctxt_switches     - 自愿上下文切换(等待资源)
# nonvoluntary_ctxt_switches  - 非自愿上下文切换(时间片到期)
网络连接
# 查看进程的网络连接
cat /proc/PID/net/tcp
cat /proc/PID/net/udp
# 或使用 netstat/lsof
netstat -anp | grep PID
lsof -p PID -i
资源限制
# 查看进程的资源限制
cat /proc/PID/limits
# 字段说明:
# Limit           - 资源类型
# Soft Limit      - 软限制(可超过但会收到信号)
# Hard Limit      - 硬限制(不可超过)
# Units           - 单位
环境变量
# 查看进程的环境变量
cat /proc/PID/environ | tr '\0' '\n'
# 查找特定环境变量
cat /proc/PID/environ | tr '\0' '\n' | grep VARIABLE_NAME
命令行和工作目录
# 查看命令行参数
cat /proc/PID/cmdline | tr '\0' ' '
# 查看工作目录
readlink /proc/PID/cwd
# 查看可执行文件路径
readlink /proc/PID/exe
内存映射详情
# 查看详细的内存映射
cat /proc/PID/maps
# 查看内存映射摘要
cat /proc/PID/smaps
# smaps 提供更详细的信息:
# - 每个映射区域的详细统计
# - 共享/私有内存大小
# - 脏页统计
# - 交换分区使用
进程关系
# 查看进程树
pstree -p PID
# 查看子进程
ps --ppid PID
# 查看进程会话和进程组
cat /proc/PID/stat | awk '{print "会话ID: " $6 " 进程组: " $5}'

Cgroup 资源监控

Cgroup v1 文件系统

如果进程在 cgroup 中运行(如 Docker 容器、systemd 服务),可以通过 cgroup 文件系统查看资源使用:

# 查找进程的 cgroup 路径
cat /proc/PID/cgroup
# 查看 CPU 使用(如果使用 CPU cgroup)
cat /sys/fs/cgroup/cpu/cgroup_name/cpuacct.usage
cat /sys/fs/cgroup/cpu/cgroup_name/cpu.stat
# 查看内存使用(如果使用 Memory cgroup)
cat /sys/fs/cgroup/memory/cgroup_name/memory.usage_in_bytes
cat /sys/fs/cgroup/memory/cgroup_name/memory.stat
cat /sys/fs/cgroup/memory/cgroup_name/memory.limit_in_bytes
# 查看 I/O 统计(如果使用 blkio cgroup)
cat /sys/fs/cgroup/blkio/cgroup_name/blkio.io_service_bytes
cat /sys/fs/cgroup/blkio/cgroup_name/blkio.io_serviced
# 查看进程数限制
cat /sys/fs/cgroup/pids/cgroup_name/pids.current
cat /sys/fs/cgroup/pids/cgroup_name/pids.max

Cgroup v2 文件系统

现代 Linux 系统使用 cgroup v2:

# 查找进程的 cgroup 路径
cat /proc/PID/cgroup
# 查看资源统计(统一接口)
cat /sys/fs/cgroup/cgroup_name/cpu.stat
cat /sys/fs/cgroup/cgroup_name/memory.current
cat /sys/fs/cgroup/cgroup_name/memory.stat
cat /sys/fs/cgroup/cgroup_name/io.stat
# 查看资源限制
cat /sys/fs/cgroup/cgroup_name/memory.max
cat /sys/fs/cgroup/cgroup_name/cpu.max

systemd 服务资源监控

# 查看服务的资源使用
systemd-cgtop
# 查看特定服务的统计
systemctl status service-name
systemd-cgtop /system.slice/service-name.service
# 查看服务资源限制配置
systemctl show service-name | grep -i limit

Docker 容器资源监控

# 查看容器的资源使用
docker stats container_name
# 查看容器的详细资源统计
docker stats --no-stream container_name
# 查看容器的 cgroup 信息
docker inspect container_name | grep -i cgroup
# 进入容器查看
docker exec container_name cat /proc/self/cgroup

高级监控工具

bpftrace(动态追踪)

安装:

# Ubuntu 20.04+
sudo apt-get install bpftrace
# 或从源码编译

基本用法:

# 实时监控 CPU 使用(按用户态堆栈)
bpftrace -e 'profile:hz:99 /pid == PID/ { @[ustack] = count(); }'
# 监控系统调用
bpftrace -e 'tracepoint:syscalls:sys_enter_* /pid == PID/ { @[probe] = count(); }'
# 监控 I/O 操作
bpftrace -e 'tracepoint:block:block_rq_issue /pid == PID/ { @[comm] = count(); }'
# 监控内存分配
bpftrace -e 'uprobe:/lib/x86_64-linux-gnu/libc.so.6:malloc /pid == PID/ { @[ustack] = count(); }'

perf(性能分析)

安装:

# Ubuntu/Debian
sudo apt-get install linux-perf
# CentOS/RHEL
sudo yum install perf

基本用法:

# 实时查看热点函数
perf top -p PID
# 记录性能数据
perf record -p PID -g sleep 10
# 查看报告
perf report
# 统计系统调用
perf stat -p PID sleep 5
# 追踪特定事件
perf trace -p PID

strace(系统调用追踪)

基本用法:

# 追踪系统调用并统计
strace -cp PID
# 追踪特定系统调用
strace -e trace=open,read,write -p PID
# 显示时间戳
strace -t -p PID
# 统计系统调用耗时
strace -c -p PID

关键指标说明

指标对照表

指标命令/文件说明正常范围参考
CPU 使用ps -o %cpu进程占用 CPU 百分比0-100%
内存使用ps -o %mem,rss,vsz%mem=物理内存百分比,rss=实际物理内存(KB),vsz=虚拟内存大小(KB)根据系统内存调整
线程数ls /proc/PID/task任务目录数量即为线程数根据应用类型
I/O 读取/proc/PID/ioread_bytes 显示实际磁盘读取根据应用需求
I/O 写入/proc/PID/iowrite_bytes 显示实际磁盘写入根据应用需求
上下文切换/proc/PID/statusvoluntary_ctxt_switches/nonvoluntary_ctxt_switches过高可能存在问题
运行时间ps -o etime进程已运行时间 (格式: [[DD-]hh:]mm:ss)-
文件描述符ls /proc/PID/fd打开的文件描述符数量注意是否有泄漏

内存相关指标详解

  • VIRT (Virtual Memory Size): 进程使用的虚拟内存总量,包括代码、数据、共享库等
  • RES (Resident Set Size): 进程实际使用的物理内存,不包括交换分区
  • SHR (Shared Memory): 共享内存大小,可能被多个进程共享
  • %MEM: RES 占系统总物理内存的百分比

CPU 相关指标详解

  • %CPU: 进程在采样周期内的 CPU 使用百分比,可能超过 100%(多核系统)
  • 用户态时间: 进程在用户空间执行的时间
  • 内核态时间: 进程在内核空间执行的时间(系统调用)

常见问题排查

1. CPU 使用率过高

诊断步骤:

# 查看 CPU 热点函数
perf top -p PID
# 统计系统调用
strace -cp PID
# 查看线程 CPU 使用
top -H -p PID
# 使用 bpftrace 追踪
bpftrace -e 'profile:hz:99 /pid == PID/ { @[ustack] = count(); }'

可能原因:

  • 无限循环或死循环
  • 频繁的系统调用
  • 计算密集型任务
  • 锁竞争导致的忙等待

2. 内存使用过高

诊断步骤:

# 查看详细内存映射
pmap -x PID
# 查看内存使用趋势
watch -n 1 'ps -p PID -o pid,%mem,rss,vsz'
# 使用 gdb 查看内存区域
gdb -p PID -ex "info proc mappings" --batch
# 检查内存泄漏(需要持续监控)
valgrind --leak-check=full ./program

可能原因:

  • 内存泄漏
  • 缓存过大
  • 数据结构设计不合理
  • 内存碎片

3. I/O 瓶颈

诊断步骤:

# 实时监控 I/O
iotop -p PID
# 查看 I/O 统计
cat /proc/PID/io
# 使用 SystemTap 追踪文件操作(需要 root)
stap -e 'probe vfs.* { if (pid() == PID) printf("%s\n", pp()) }'
# 查看磁盘使用情况
iostat -x 1

可能原因:

  • 频繁的小文件读写
  • 未使用缓冲
  • 磁盘性能瓶颈
  • 网络 I/O 延迟

4. 线程/进程过多

诊断步骤:

# 查看线程数量
ls /proc/PID/task | wc -l
# 查看线程详情
ps -T -p PID
# 查看进程树
pstree -p PID

5. 文件描述符泄漏

诊断步骤:

# 监控文件描述符数量
watch -n 1 'ls /proc/PID/fd | wc -l'
# 查看打开的文件
lsof -p PID
# 查看具体文件类型分布
ls -l /proc/PID/fd | awk '{print $NF}' | xargs -I {} readlink {} | sort | uniq -c

自动化监控脚本

综合监控脚本

创建一个综合监控脚本,定期采集进程的各项资源指标:

#!/bin/bash
# 进程资源监控脚本
# 用法: ./monitor_process.sh <PID> [interval] [count]
  if [ -z "$1" ]; then
  echo "用法: $0 <PID> [刷新间隔(秒)] [监控次数]"
    echo "示例: $0 12345 2 10"
    exit 1
    fi
    PID=$1
    INTERVAL=${2:-2}
    COUNT=${3:-5}
    # 检查进程是否存在
    if ! kill -0 $PID 2>/dev/null; then
    echo "错误: 进程 $PID 不存在"
    exit 1
    fi
    echo "===== 进程 $PID 资源监控 (每 ${INTERVAL} 秒刷新,共 ${COUNT} 次) ====="
    echo ""
    for i in $(seq 1 $COUNT); do
    echo "--- 第 $i 次监控 ($(date '+%Y-%m-%d %H:%M:%S')) ---"
    # 基本信息
    echo "【基本信息】"
    ps -p $PID -o user,pid,ppid,ni,%cpu,%mem,vsz,rss,tty,stat,start,time,cmd --no-headers 2>/dev/null || echo "进程已结束"
    # CPU 使用
    if [ -f /proc/$PID/stat ]; then
    echo -e "\n【CPU 使用】"
    cat /proc/$PID/stat | awk '{
    utime = $14
    stime = $15
    cutime = $16
    cstime = $17
    total = utime + stime + cutime + cstime
    printf "用户态CPU: %d 时钟周期\n", utime
    printf "内核态CPU: %d 时钟周期\n", stime
    printf "子进程用户态: %d 时钟周期\n", cutime
    printf "子进程内核态: %d 时钟周期\n", cstime
    printf "总CPU时间: %d 时钟周期\n", total
    }'
    fi
    # 内存使用
    if [ -f /proc/$PID/status ]; then
    echo -e "\n【内存使用】"
    grep -E 'VmPeak|VmSize|VmRSS|VmSwap|VmHWM|VmData|VmStk|VmExe' /proc/$PID/status
    fi
    # I/O 统计
    if [ -f /proc/$PID/io ]; then
    echo -e "\n【I/O 统计】"
    cat /proc/$PID/io
    fi
    # 打开文件描述符
    if [ -d /proc/$PID/fd ]; then
    echo -e "\n【打开文件描述符数量】"
    echo "$(ls -l /proc/$PID/fd 2>/dev/null | wc -l) 个"
    fi
    # 线程数
    if [ -d /proc/$PID/task ]; then
    echo -e "\n【线程数】"
    echo "$(ls /proc/$PID/task 2>/dev/null | wc -l) 个"
    fi
    # 上下文切换
    if [ -f /proc/$PID/status ]; then
    echo -e "\n【上下文切换】"
    grep -E 'voluntary_ctxt_switches|nonvoluntary_ctxt_switches' /proc/$PID/status
    fi
    echo ""
    echo "=========================================="
    echo ""
    if [ $i -lt $COUNT ]; then
    sleep $INTERVAL
    fi
    done
    echo "监控完成"

保存监控数据脚本

#!/bin/bash
# 将监控数据保存到文件
# 用法: ./save_monitor.sh <PID> <output_file> [interval]
  PID=$1
  OUTPUT=${2:-"monitor_${PID}_$(date +%Y%m%d_%H%M%S).log"}
  INTERVAL=${3:-5}
  echo "开始监控进程 $PID,数据保存到 $OUTPUT"
  echo "监控间隔: ${INTERVAL} 秒,按 Ctrl+C 停止"
  while true; do
  TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
  # 检查进程是否存在
  if ! kill -0 $PID 2>/dev/null; then
  echo "[$TIMESTAMP] 进程已结束" >> "$OUTPUT"
  break
  fi
  # 采集数据
  {
  echo "===== $TIMESTAMP ====="
  ps -p $PID -o pid,%cpu,%mem,vsz,rss,cmd --no-headers
  [ -f /proc/$PID/status ] && grep -E 'VmRSS|VmSize' /proc/$PID/status
  [ -f /proc/$PID/io ] && cat /proc/$PID/io
  echo ""
  } >> "$OUTPUT"
  sleep $INTERVAL
  done
  echo "监控数据已保存到 $OUTPUT"

工具选择建议

根据不同场景选择合适的工具:

场景推荐工具说明
快速查看ps简单快速,适合脚本集成
实时监控htoptop交互式界面,适合手动监控
详细统计pidstat适合定期采样和数据分析
历史数据sar查看历史性能数据,适合趋势分析
I/O 分析iotop专门用于 I/O 监控
内存分析pmapsmempmap 查看内存映射,smem 提供更准确的内存统计
网络连接sslsofss 更现代快速,lsof 功能更全面
文件描述符lsof查看进程打开的文件和网络连接
综合监控atop功能全面,适合系统管理员
性能分析perfbpftrace适合深度性能调优
系统调用strace追踪和统计系统调用
资源限制prlimit查看和设置进程资源限制
CPU 亲和性tasksetnumactl查看和设置 CPU 绑定和 NUMA
容器监控docker stats、cgroup监控容器资源使用
systemd 服务systemd-cgtop监控 systemd 管理的服务
自动化/proc 文件系统适合脚本和自动化工具
问题排查strace + perf + pmap综合工具定位性能问题

总结

分析 Linux 进程资源占用有多种方法,选择合适的工具可以事半功倍:

常用方法分类

  1. 日常监控

    • 实时监控:htoptopatop
    • 快照查看:pspidstat
    • 历史数据:sar(需启用 sysstat 数据收集)
  2. 专项分析

    • 内存pmap(内存映射)、smem(准确统计)、/proc/PID/smaps(详细映射)
    • I/Oiotoppidstat -d/proc/PID/io
    • 网络sslsof -inetstat
    • 文件lsof/proc/PID/fd
  3. 脚本集成

    • /proc 文件系统:最底层的信息源,适合自动化
    • ps 命令:简单快速,输出格式统一
    • pidstat:适合定期采样
  4. 性能分析

    • perf:功能强大的性能分析工具
    • bpftrace:动态追踪,灵活强大
    • strace:系统调用追踪
  5. 容器和服务监控

    • Docker:docker stats、cgroup 文件系统
    • systemd:systemd-cgtopsystemctl status
    • Cgroup:/sys/fs/cgroup/ 文件系统
  6. 系统级监控

    • vmstat:系统整体资源统计
    • sar:历史性能数据
    • slabtop:内核缓存监控

关键指标

  • CPU: %cpu、用户态/内核态时间、CPU 亲和性
  • 内存: RSS(物理内存)、VSZ(虚拟内存)、PSS(比例集大小)、内存映射
  • I/O: read_byteswrite_bytes、I/O 速率
  • 网络: 连接数、连接状态、端口占用
  • 其他: 线程数、文件描述符数、上下文切换次数、资源限制

最佳实践

  1. 定期监控:建立监控机制,定期采集关键指标
  2. 建立基线:记录正常情况下的资源使用,便于对比
  3. 组合使用:根据问题类型组合使用多个工具
  4. 自动化:使用脚本自动化监控和告警
  5. 历史数据:启用 sar 数据收集,便于问题回溯
  6. 容器环境:在容器环境中使用 cgroup 相关工具

问题排查流程

  1. 快速定位:使用 htoptop 快速查看资源占用
  2. 详细分析:使用 pidstatpmap 等工具深入分析
  3. 性能分析:使用 perfstrace 定位性能瓶颈
  4. 历史对比:使用 sar 查看历史数据,分析趋势
  5. 综合诊断:结合多个工具的结果,全面分析问题

定期监控和记录这些指标,有助于及时发现和解决性能问题。根据具体场景选择合适的工具组合,可以更高效地完成资源分析和问题排查。

posted @ 2025-12-01 19:49  gccbuaa  阅读(1)  评论(0)    收藏  举报