TCP: out of memory警告表示TCP缓冲区内存超tcp_mem硬上限(第三值),触发丢包和拒绝新连接;其三值分别定义低水位、压力启动点和硬上限,单位为页,控制全系统TCP缓冲区总用量。

tcp_mem 报错说明什么
出现 TCP: out of memory -- consider tuning tcp_mem 并不表示系统物理内存真的耗尽,而是内核 TCP 栈在分配 socket 缓冲区(sk_buff)时,发现当前使用的内存超出了 tcp_mem 设置的硬上限(第三个值)。此时内核会强制丢包、拒绝新连接,并打日志警告。
tcp_mem 三个值分别控制什么
tcp_mem 是一个三元组:low pressure high,单位是页(page,通常是 4KB):
-
low:低于此值时,TCP 缓冲区可自由增长,无压力 -
pressure:达到此值后,内核开始主动回收缓冲区(如降低rmem_max、wmem_max),避免进一步膨胀 -
high:超过此值即触发 OOM-like 行为——丢包、拒绝新连接、记录警告
注意:这三个值不是 per-socket,而是全系统所有 TCP socket 缓冲区占用的总页数上限。
如何计算合理值
推荐从系统内存和典型连接负载反推,而非套用固定数字:
- 先查当前内存页大小:
getconf PAGE_SIZE(通常为 4096) - 估算峰值并发连接数 × 平均每连接缓冲区用量(例如 128KB 接收 + 128KB 发送 ≈ 64 pages)
- 预留 20%~30% 余量,再向上取整到 2 的幂次(内核内部偏好)
- 确保
pressure≈low × 1.5,high≈low × 2~3,保持梯度合理
常见参考(基于 16GB 内存、中等吞吐 Web 服务):tcp_mem = "98304 131072 196608"(≈ 384MB / 512MB / 768MB)
高并发场景(如代理、长连接网关)可能需:tcp_mem = "262144 327680 393216"(≈ 1GB / 1.28GB / 1.5GB)
修改后必须同步调整的配套参数
只调 tcp_mem 不改其他,容易导致缓冲区实际无法撑到上限:
- 确认
net.core.rmem_max和net.core.wmem_max≥ 单连接最大期望缓冲(如262144) - 检查
net.ipv4.tcp_rmem和net.ipv4.tcp_wmem的第三个值(默认常为4194304),若远高于tcp_mem[2],会导致单连接轻易突破全局限制 - 建议将
tcp_rmem[2]和tcp_wmem[2]设为 ≤tcp_mem[2] / max_estimated_connections
例如:目标支持 10k 连接,tcp_mem[2] = 393216(1.5GB),则单连接上限不宜超过 157286(≈ 614KB)
真正难的是预估连接规模和 buffer 模式——突发流量下缓冲区会快速堆积,而 tcp_mem 是静态阈值。线上调参后务必用 ss -i 和 /proc/net/snmp 中的 TcpExt: TCPMemoryPressures 计数器验证是否仍频繁触发压力态。








