top中%cpu虚高因采样周期平滑和d状态进程不计,需调短刷新、查i/o与内存瓶颈;iostat/iotop定位磁盘争用;dmesg+meminfo排查oom真因;ss替代netstat抓网络队列与重传。

top 命令里 %CPU 虚高,实际负载不高?看 top 的默认排序和采样逻辑
Linux 卡顿但 top 显示 CPU 使用率不高,常见原因是它默认按 CPU 占用实时排序,而卡顿往往来自 I/O 等待或内存压力,top 不直接暴露这些瓶颈。
-
top默认刷新周期是 3 秒,短时突发卡顿容易被平滑掉;按s键可临时设为 1 秒甚至 0.5 秒观察瞬时峰值 - 按
1键展开所有 CPU 核心,避免单核打满但整体平均值偏低的误判 - 按
Shift + M切换到内存占用排序,RES高但%MEM持续超 80% 的进程可能触发 OOM Killer 或频繁 swap - 注意
%CPU列实际是“自上次刷新以来”的占比,不是持续占用率;如果进程处于D(不可中断睡眠)状态,它不计入 CPU 使用率,但正在等磁盘或锁——这才是真卡点
卡在读写磁盘?用 iostat 和 iotop 区分设备级和进程级 I/O
iostat -x 1 看设备层面是否饱和,iotop 定位具体哪个进程在狂刷磁盘;两者必须配合,只看一个容易误判。
-
iostat -x 1中重点关注%util(接近 100% 表示设备忙)、await(平均 I/O 等待毫秒数,>10ms 就值得查)、r/s和w/s是否异常突增 -
iotop默认不显示线程,加-P参数才能看到每个线程的真实 I/O,尤其对 Java 应用有用——GC 日志刷盘、log4j 异步队列溢出都可能表现为单个 JVM 进程下多个线程争抢 write - SSD 上
%util长期 100% 不一定代表磁盘瓶颈,可能是队列深度压满;此时要看avgqu-sz(平均队列长度),>10 就说明请求在排队 - 别信
df -h——空间够不代表性能好;xfs_info /mount/point或tune2fs -l /dev/sdX1查文件系统挂载参数,barrier=1或未启用noatime在高频小文件场景会拖慢明显
dmesg 报 Out of memory: Kill process?先确认是不是真的内存不足
OOM Killer 日志出现不等于物理内存耗尽,更可能是内核认为某个内存域(如 DMA32)无法分配连续页,或者 cgroup 限额被突破。
- 运行
dmesg -T | grep -i "killed process"后,立刻跟cat /proc/meminfo,重点看MemAvailable(不是MemFree)——若该值仍 >500MB,大概率是 cgroup 限制或 slab 泄漏 - 检查
/sys/fs/cgroup/memory/下各子目录的memory.limit_in_bytes和memory.usage_in_bytes,Docker 容器或 systemd service 都可能静默设了内存上限 -
slabtop看Active / Total比例,若size-4096或dentry类目占总 slab 超 60%,说明内核缓存没及时回收,常见于大量小文件操作后未 sync - 某些驱动(如老版本 NVIDIA GPU 驱动)会锁定大量内存进显存,
nvidia-smi -q -d MEMORY和cat /proc/driver/nvidia/params | grep -i "lock"可交叉验证
网络相关卡顿?ss 比 netstat 更准,且要盯住重传和连接队列
网络延迟高或连接超时,往往不是带宽问题,而是本地 socket 队列堆积或 TCP 重传异常,ss 能直接暴露这些细节。
-
ss -i显示每个连接的 TCP 信息,重点关注retrans(重传次数)、rcv_rtt(接收端 RTT)、q字段(如q:0表示发送队列空,q:1234表示有数据待发) -
ss -s看全局 socket 统计,若tcp行中inuse高但orphan(无应用关联的连接)也高,说明应用没正确 close,TIME_WAIT 泛滥或连接池泄漏 -
ss -ltnp查监听端口,对比netstat -tulnp,若后者卡住或报can't identify protocol,说明 procfs 权限或内核模块异常,ss更轻量可靠 - 检查
/proc/sys/net/ipv4/tcp_retries2,默认值 15 意味着重传约 15 分钟才断连;若业务要求快速失败,可调低到 3~5,但需同步调整应用层超时逻辑










