首页/网络/网络排障速查/ss -m:socket 内存与缓冲(skmem)

ss -m:socket 内存与缓冲(skmem)

排查 socket 占内存与缓冲区耗尽:-m 展开 skmem 字段,r/t 是实际分配、rb/tb 是内核自动调优上限,配合状态过滤找出占用大户。

网络排障速查网络更新于 2026-10-13

ss -m 是什么

ss 加 -m 会展开每个 socket 的 skmem 内存记账字段,用于判断『socket 到底吃了多少内存、缓冲是否被耗尽』。要区分两类数字:r/t 是当前实际分配量,rb/tb 是内核自动调优的上限;把上限当成实际占用会导致误判内存泄漏。看到 d(drop)不为零,往往正是业务侧表现为卡顿却查不到丢包的原因。

基本信息

适用平台Linux(iproute2 的 ss,内核 4.x 以上输出完整)
关键选项-t TCP、-m 内存、-n 数字、state 过滤
字段含义r/rb 接收已分配与上限、t/tb 发送已分配与上限、w 待分配写队列
配套命令/proc/net/sockstat、ss -s 汇总

典型使用场景

  • 怀疑句柄或缓冲占用过高:按状态与端口过滤,找出占用大户
  • 业务卡顿但链路正常:检查 skmem 的 drop 计数是否为非零
  • 排查内存增长的来源:区分内核 socket 内存与应用堆内存
  • 数据库连接数评估:按端口过滤统计每个连接的缓冲占用

内存视图

内存视图
# 查看已建立连接的 socket 内存明细
ss -tmn state established | head -20
# skmem 字段示例:
# skmem:(r0,rb131072,t0,tb16384,f0,w0,o0,bl0,d0)
# 只看与数据库端口相关的连接
ss -tmn '( dport = :3306 )' | head
# 汇总视角:各类 socket 数量
ss -s | head -10

skmem 字段判读

字段含义判读要点
r 与 rb接收缓冲:已分配与上限判断实际占用要看 r,不要看 rb
t 与 tb发送缓冲:已分配与上限配合 Send-Q 判断哪一侧在积压
w待分配写队列字节持续不为零说明写侧承压
ooptmem 辅助数据缓冲大量小连接时该值会明显上升
d已丢弃字节非零即为真实丢数据,需重点解释
rb/tb 是内核自动调优的上限而非真实占用:看到 rb=131072 不代表每个连接吃掉 128KB。判断内存是否异常,要看 r/t 的实际值以及 sockstat 的汇总趋势。
看到 d 非零时不要只调大缓冲:它说明收包时缓冲曾不足,根因可能是应用读取过慢或突发流量超出预期,需要两侧同时分析。

易错点

  • 把 rb/tb 上限当实际占用:误判为内存泄漏,浪费大量排查时间
  • 忽略 d(drop)非零:业务侧的间歇卡顿在那里已经有直接证据
  • 只在单机看 socket 内存:总量增长可能来自连接数增加而非单连接变大
  • 忘记加 -n:DNS 异常时命令自己卡住,现场取证效率骤降
  • 把 socket 内存与应用堆内存混为一谈:两者定位手段不同,混在一起会找不到真凶

数据来源与参考

  • man 8 ss(iproute2)
  • Linux 内核 TCP 内存记账说明

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌