Linux 进程资源占用分析指南

Linux 进程资源占用分析指南

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

目录

快速开始

前提条件

  • 已知进程 ID (PID)

  • 获取 PID 的方法:

    bash 复制代码
    # 通过进程名查找
    pgrep process_name
    ps aux | grep process_name
    
    # 通过端口查找
    lsof -i :port
    netstat -tlnp | grep :port

命令行工具

1. top 命令(实时监控)

基本用法:

bash 复制代码
top -p PID

交互式操作:

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

输出说明:

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

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

基本用法:

bash 复制代码
htop -p PID

功能特点:

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

快捷键:

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

3. ps 命令(快照查看)

基本资源查看:

bash 复制代码
ps -p PID -o pid,ppid,%cpu,%mem,vsz,rss,cmd

详细资源报告:

bash 复制代码
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 - 进程状态

连续监控:

bash 复制代码
watch -n 1 'ps -p PID -o pid,%cpu,%mem,vsz,rss,cmd'

4. pidstat(详细资源统计)

安装:

bash 复制代码
# Ubuntu/Debian
sudo apt-get install sysstat

# CentOS/RHEL
sudo yum install sysstat

基本用法:

bash 复制代码
# 每2秒刷新一次,共显示5次
pidstat -p PID 2 5

详细资源监控:

bash 复制代码
# 磁盘 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(高级监控)

安装:

bash 复制代码
# Ubuntu/Debian
sudo apt-get install atop

# CentOS/RHEL
sudo yum install atop

基本用法:

bash 复制代码
atop -p PID

功能亮点:

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

快捷键:

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

6. nmon(可视化监控)

安装:

bash 复制代码
# Ubuntu/Debian
sudo apt-get install nmon

# CentOS/RHEL
sudo yum install nmon

基本用法:

bash 复制代码
nmon -p PID

交互式界面:

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

7. iotop(I/O 监控)

安装:

bash 复制代码
# Ubuntu/Debian
sudo apt-get install iotop

# CentOS/RHEL
sudo yum install iotop

基本用法:

bash 复制代码
# 实时监控指定进程的 I/O
iotop -p PID

# 显示累计 I/O
iotop -a -p PID

输出说明:

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

8. lsof(列出打开文件)

基本用法:

bash 复制代码
# 查看进程打开的所有文件
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(系统活动报告)

安装:

bash 复制代码
# Ubuntu/Debian
sudo apt-get install sysstat

# CentOS/RHEL
sudo yum install sysstat

基本用法:

bash 复制代码
# 查看当前 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(虚拟内存统计)

基本用法:

bash 复制代码
# 每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(内存映射查看)

基本用法:

bash 复制代码
# 查看进程的内存映射
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(内存使用统计)

安装:

bash 复制代码
# Ubuntu/Debian
sudo apt-get install smem

# CentOS/RHEL
sudo yum install smem

基本用法:

bash 复制代码
# 查看进程内存使用(按 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(现代网络连接工具)

基本用法:

bash 复制代码
# 查看进程的网络连接
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 命令(执行时间统计)

基本用法:

bash 复制代码
# 使用 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)

基本用法:

bash 复制代码
# 查看进程的 CPU 亲和性
taskset -p PID

# 查看进程的 NUMA 节点
numactl --show

# 查看进程的 NUMA 统计
numastat -p PID

# 查看系统 NUMA 信息
numactl --hardware

用途:

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

16. prlimit(资源限制查看)

基本用法:

bash 复制代码
# 查看进程的资源限制
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 进程组监控)

基本用法:

bash 复制代码
# 查看 systemd 管理的进程组资源使用
systemd-cgtop

# 查看特定服务的资源使用
systemd-cgtop /system.slice/service-name.service

# 查看用户服务的资源使用
systemd-cgtop /user.slice/user-1000.slice

适用场景:

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

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

基本用法:

bash 复制代码
# 实时查看内核 slab 缓存使用
slabtop

# 按使用量排序
slabtop -s c

# 只显示正在使用的缓存
slabtop -o

用途:

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

系统文件分析

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

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

CPU 使用情况
bash 复制代码
# 查看进程 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
内存使用情况
bash 复制代码
# 查看内存详细信息
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)
打开文件描述符
bash 复制代码
# 查看打开的文件描述符数量
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 统计
bash 复制代码
# 查看 I/O 统计信息
cat /proc/PID/io

# 输出字段说明:
# rchar        - 读取字符数(包括缓存)
# wchar        - 写入字符数(包括缓存)
# syscr        - 系统调用读取次数
# syscw        - 系统调用写入次数
# read_bytes   - 实际磁盘读取字节数
# write_bytes  - 实际磁盘写入字节数
# cancelled_write_bytes - 取消的写入字节数
线程信息
bash 复制代码
# 查看线程数量
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
上下文切换
bash 复制代码
# 查看上下文切换统计
cat /proc/PID/status | grep -E 'voluntary_ctxt_switches|nonvoluntary_ctxt_switches'

# 字段说明:
# voluntary_ctxt_switches     - 自愿上下文切换(等待资源)
# nonvoluntary_ctxt_switches  - 非自愿上下文切换(时间片到期)
网络连接
bash 复制代码
# 查看进程的网络连接
cat /proc/PID/net/tcp
cat /proc/PID/net/udp

# 或使用 netstat/lsof
netstat -anp | grep PID
lsof -p PID -i
资源限制
bash 复制代码
# 查看进程的资源限制
cat /proc/PID/limits

# 字段说明:
# Limit           - 资源类型
# Soft Limit      - 软限制(可超过但会收到信号)
# Hard Limit      - 硬限制(不可超过)
# Units           - 单位
环境变量
bash 复制代码
# 查看进程的环境变量
cat /proc/PID/environ | tr '\0' '\n'

# 查找特定环境变量
cat /proc/PID/environ | tr '\0' '\n' | grep VARIABLE_NAME
命令行和工作目录
bash 复制代码
# 查看命令行参数
cat /proc/PID/cmdline | tr '\0' ' '

# 查看工作目录
readlink /proc/PID/cwd

# 查看可执行文件路径
readlink /proc/PID/exe
内存映射详情
bash 复制代码
# 查看详细的内存映射
cat /proc/PID/maps

# 查看内存映射摘要
cat /proc/PID/smaps

# smaps 提供更详细的信息:
# - 每个映射区域的详细统计
# - 共享/私有内存大小
# - 脏页统计
# - 交换分区使用
进程关系
bash 复制代码
# 查看进程树
pstree -p PID

# 查看子进程
ps --ppid PID

# 查看进程会话和进程组
cat /proc/PID/stat | awk '{print "会话ID: " $6 " 进程组: " $5}'

Cgroup 资源监控

Cgroup v1 文件系统

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

bash 复制代码
# 查找进程的 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:

bash 复制代码
# 查找进程的 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 服务资源监控

bash 复制代码
# 查看服务的资源使用
systemd-cgtop

# 查看特定服务的统计
systemctl status service-name
systemd-cgtop /system.slice/service-name.service

# 查看服务资源限制配置
systemctl show service-name | grep -i limit

Docker 容器资源监控

bash 复制代码
# 查看容器的资源使用
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(动态追踪)

安装:

bash 复制代码
# Ubuntu 20.04+
sudo apt-get install bpftrace

# 或从源码编译

基本用法:

bash 复制代码
# 实时监控 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(性能分析)

安装:

bash 复制代码
# Ubuntu/Debian
sudo apt-get install linux-perf

# CentOS/RHEL
sudo yum install perf

基本用法:

bash 复制代码
# 实时查看热点函数
perf top -p PID

# 记录性能数据
perf record -p PID -g sleep 10

# 查看报告
perf report

# 统计系统调用
perf stat -p PID sleep 5

# 追踪特定事件
perf trace -p PID

strace(系统调用追踪)

基本用法:

bash 复制代码
# 追踪系统调用并统计
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/io read_bytes 显示实际磁盘读取 根据应用需求
I/O 写入 /proc/PID/io write_bytes 显示实际磁盘写入 根据应用需求
上下文切换 /proc/PID/status voluntary_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 使用率过高

诊断步骤:

bash 复制代码
# 查看 CPU 热点函数
perf top -p PID

# 统计系统调用
strace -cp PID

# 查看线程 CPU 使用
top -H -p PID

# 使用 bpftrace 追踪
bpftrace -e 'profile:hz:99 /pid == PID/ { @[ustack] = count(); }'

可能原因:

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

2. 内存使用过高

诊断步骤:

bash 复制代码
# 查看详细内存映射
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 瓶颈

诊断步骤:

bash 复制代码
# 实时监控 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. 线程/进程过多

诊断步骤:

bash 复制代码
# 查看线程数量
ls /proc/PID/task | wc -l

# 查看线程详情
ps -T -p PID

# 查看进程树
pstree -p PID

5. 文件描述符泄漏

诊断步骤:

bash 复制代码
# 监控文件描述符数量
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

自动化监控脚本

综合监控脚本

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

bash 复制代码
#!/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 "监控完成"

保存监控数据脚本

bash 复制代码
#!/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 监控
内存分析 pmapsmem pmap 查看内存映射,smem 提供更准确的内存统计
网络连接 sslsof ss 更现代快速,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. 综合诊断:结合多个工具的结果,全面分析问题

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

相关推荐
samroom3 小时前
Linux系统管理与常用命令详解
linux·运维·服务器
PKNLP3 小时前
07.docker介绍与常用命令
运维·docker·容器
Mxsoft6193 小时前
电力系统AR远程运维与数字孪生交互技术
运维·ar
一叶之秋14123 小时前
Linux基本指令
linux·运维·服务器
码割机3 小时前
Linux服务器安装jdk和maven详解
java·linux·maven
亚林瓜子4 小时前
在amazon linux 2023上面源码手动安装tesseract5.5.1
linux·运维·服务器·ocr·aws·ec2
爱学习的大牛1234 小时前
Ubuntu 24.04 安装 FreeSWITCH 完整教程
linux·freeswitch
FreeBuf_4 小时前
研究人员披露 Windows SMB 服务器权限提升漏洞(CVE-2025-58726)
运维·服务器·windows
go_bai4 小时前
Linux--进程池
linux·c++·经验分享·笔记·学习方法