Linux CPU与内存调优实战:从假死到零假死的防假死指南

LinuxCPU调优内存调优
于 2026-10-02 03:56:40 修改
·本内容遵循CC 4.0 BY-SA版权协议

1. 从一次线上告警说起:为什么“防假死”比调优本身更重要

凌晨两点,监控大屏上跳出一条告警:一台跑了三年多的业务服务器,CPU 使用率从平时的 30% 一路飙到 98%,SSH 连上去敲个 ls 都要等十几秒才回显,top 命令刷出来一片红。运维同事第一反应是“哪个进程在吃 CPU”,结果 top 里排第一的进程 CPU 占用只有 12%,剩下的全是 %wa(IO 等待)和 %si(软中断)在偷偷吃掉算力。更诡异的是,内存看着还剩 2GB,但系统就是卡到几乎无法操作,最后只能硬重启。

这个场景我相信做过 Linux 运维的朋友都不陌生。它有个很形象的名字——假死。系统没真死,进程还在跑,但你已经失去了对它的有效控制能力。而“跳出网络与文件系统”这句话,恰恰点出了很多人排查时的思维盲区:一遇到卡顿就去看网络连接、看磁盘 IO、看日志文件,却忽略了 CPU 调度和内存回收这两个最底层、也最容易引发连锁反应的环节。

这篇内容我想聊的就是围绕 Linux CPU 与内存调优 的“防假死”实战。它不是什么高深的内核源码分析,而是我在实际运维中反复踩坑、反复验证后总结出的一套可落地的方法论。适合谁看?如果你是中高级运维、后端开发、SRE,或者只是自己维护几台云主机、NAS、家庭服务器的折腾党,只要你的系统出现过“CPU 不高但就是卡”“内存没满但进程被 OOM 干掉”“SSH 能连但命令不响应”这类问题,这篇内容都能给你直接抄作业的方案。

核心关键词就四个:Linux、CPU、内存调优、防假死。我会从整体设计思路讲起,拆解 CPU 调度和内存回收的底层逻辑,然后给出具体的参数配置、排查命令和实战案例,最后整理一份常见问题速查表。全程不堆砌术语,尽量用生活化的类比把原理讲透,让你不仅知道怎么调,还知道为什么这么调。

2. 整体设计思路:防假死的本质是“保命通道”优先

2.1 假死的三种典型形态与根因定位

在动手调优之前,得先搞清楚“假死”到底分几种。我把它归纳为三类,每类的根因和应对策略完全不同。

第一类是 CPU 调度饥饿型假死。表现是系统负载(load average)极高,但 CPU 使用率看起来不高,或者某个核心被单个进程 100% 占满。根因通常是进程数远超 CPU 核心数,调度器在疯狂切换上下文,或者有进程陷入不可中断睡眠(D 状态)导致调度队列堵塞。这时候你敲命令,shell 进程根本抢不到 CPU 时间片,自然就“假死”了。

第二类是 内存回收风暴型假死。表现是内存接近耗尽,系统开始频繁进行直接内存回收(direct reclaim),%sy(系统态 CPU)飙升,%wa 也高。根因是 page cache 和匿名页的回收压力太大,内核把大量时间花在扫描 LRU 链表和回写脏页上,用户态进程被拖死。这种假死最容易被误判为“磁盘 IO 问题”,因为 %wa 确实很高。

第三类是 OOM 连锁反应型假死。表现是系统突然卡顿,然后关键进程被 OOM Killer 干掉,甚至 SSH 都连不上。根因是内存超卖严重,或者某个进程内存泄漏,触发内核的 OOM 机制。更麻烦的是,OOM Killer 的选择逻辑不一定符合你的预期,它可能干掉了数据库而不是那个泄漏的脚本。

提示:这三种假死经常同时出现。CPU 饥饿会导致内存回收变慢,内存回收风暴又会加剧 CPU 系统态开销,最终一起触发 OOM。所以防假死不能只调一个参数,要成体系地设计。

2.2 为什么“跳出网络与文件系统”是关键

很多人排查卡顿的第一反应是 netstat、ss、iostat、df -h,这些工具当然有用,但它们反映的是“结果”而不是“原因”。网络连接数暴涨可能是 CPU 调度延迟导致的 accept 队列堆积;磁盘 IO 高可能是内存回收在疯狂回写脏页。如果你只盯着网络和文件系统调,就会陷入“按下葫芦浮起瓢”的循环。

我的思路是:把 CPU 和内存当作系统的“心肺功能”来调,网络和文件系统当作“四肢”来观察。 心肺出问题,四肢必然乏力;但四肢乏力不一定是四肢本身的问题。所以防假死的第一原则是——保证系统在任何压力下,都有一条“保命通道”能让管理员登录、能执行关键命令、能优雅重启服务。

这条保命通道靠什么保障?靠三样东西:CPU 调度预留、内存回收预留、IO 优先级预留。 下面我会逐一拆解。

2.3 调优方案的整体框架

我习惯把防假死调优分成四层,从下到上依次是:

层级 调优对象 核心目标 关键手段
第一层 内核调度器 保证交互进程能抢到 CPU cgroup CPU 预留、调度策略调整
第二层 内存回收 避免 direct reclaim 风暴 vm.min_free_kbytes、watermark 调整
第三层 OOM 机制 让该杀的进程被杀,不该杀的活着 oom_score_adj、cgroup 内存限制
第四层 监控与自愈 提前发现假死前兆 PSI 压力指标、告警阈值

这个框架的好处是,每一层都有明确的“为什么”。比如第一层为什么要用 cgroup 而不是 nice 值?因为 nice 值只能调整相对优先级,在极端压力下,高 nice 的进程依然可能被饿死;而 cgroup 的 CPU 带宽控制可以硬性预留一个核心给管理通道。这就是“知其所以然”。

3. 核心细节解析:CPU 调度与内存回收的底层逻辑

3.1 CPU 调度:为什么你的 SSH 会卡住

Linux 的 CFS(完全公平调度器)核心思想是“按权重分配 CPU 时间”。每个进程有一个 vruntime(虚拟运行时间),调度器总是选择 vruntime 最小的进程运行。这个设计在正常情况下很公平,但在极端压力下有个致命问题:如果就绪队列里有几百个进程,每个进程的 vruntime 都会增长得很慢,但切换频率会急剧上升,导致上下文切换开销吃掉大量 CPU。

更麻烦的是,CFS 对“交互式进程”的识别并不完美。SSH 登录后的 shell 进程,在调度器眼里和后台的批处理脚本没有本质区别。当系统负载达到几百时,你的 shell 进程可能排在就绪队列的末尾,等上几秒才能拿到一个时间片。这就是“SSH 能连但命令不响应”的根本原因。

那怎么解决?有两个方向。一是减少就绪队列长度,把非关键进程用 cgroup 限制住,不让它们无限抢占 CPU。二是给关键进程更高的调度优先级,比如用 chrt 把 SSH 服务设成实时调度策略,或者用 cgroup 的 cpu.weight 给管理通道更高的权重。

我实测下来,最稳的方案是 cgroup v2 的 CPU 带宽控制 + 权重分配。具体来说,创建两个 cgroup:一个叫 critical,给 SSH、监控 agent、日志采集器用,设置 cpu.weight=10000;另一个叫 batch,给业务进程用,设置 cpu.weight=100。这样即使业务进程把 CPU 跑满,critical 组里的进程依然能拿到足够的 CPU 时间。

注意:cgroup v2 的 cpu.weight 范围是 1 到 10000,默认值是 100。权重是相对值,不是绝对值。如果你给 critical 设 10000,给 batch 设 100,那么 CPU 时间的分配比例大约是 100:1。但实际效果还取决于两个组里有多少进程在跑。

3.2 内存回收:watermark 与 direct reclaim 的博弈

Linux 内存管理里有个关键概念叫 watermark(水位线)。每个内存 zone 有三个水位线:min、low、high。当空闲内存高于 high 时,内核觉得内存充足;低于 low 时,唤醒 kswapd 后台回收;低于 min 时,触发 direct reclaim,也就是让分配内存的进程自己去做回收。

direct reclaim 是假死的罪魁祸首之一。因为它是同步的,进程在申请内存时被强制去扫描 LRU 链表、回写脏页,这个过程中进程处于 D 状态(不可中断睡眠),既不能响应信号,也不能被调度。如果多个进程同时触发 direct reclaim,系统就会陷入“回收风暴”,CPU 系统态飙升,用户态进程全部卡住。

那怎么避免?核心是让 kswapd 有足够的时间提前回收,而不是等到 min 水位才被动触发 direct reclaim。 具体做法是调大 vm.min_free_kbytes,让 min 水位更高,给 kswapd 留出更多缓冲空间。

vm.min_free_kbytes 的默认值是根据内存大小自动计算的,公式大致是:

TEXT
min_free_kbytes = sqrt(lowmem_kbytes * 16)

其中 lowmem_kbytes 是低端内存的大小(KB)。对于一台 16GB 内存的机器,默认值可能在 64MB 左右。这个值在内存压力大时明显不够。我的经验是,对于 16GB 到 64GB 的服务器,把 vm.min_free_kbytes 设成 1GB 到 2GB 比较稳妥;对于 128GB 以上的大内存机器,可以设成 2GB 到 4GB。

但也不能设太大,否则会浪费内存,而且可能触发更频繁的回收。我一般会结合 vm.watermark_scale_factor 一起调。这个参数控制 low 和 high 水位相对于 min 的间距,默认是 10(表示 0.1%)。把它调大到 100 到 200,可以让 kswapd 更早启动,进一步降低 direct reclaim 的概率。

3.3 OOM Killer:如何让该活的活着

OOM Killer 的选择逻辑基于 oom_score,这个分数由进程的内存占用、运行时间、nice 值等因素综合计算。但默认逻辑有个问题:它倾向于杀掉占用内存最多的进程,而这个进程往往是你的核心业务(比如数据库),而不是那个内存泄漏的脚本。

解决方法是手动调整 oom_score_adj。这个值的范围是 -1000 到 1000。设为 -1000 表示“永远不杀”,设为 1000 表示“优先杀”。我通常会把 SSH、systemd、监控 agent 的 oom_score_adj 设成 -1000,把批处理脚本、临时任务设成 500 到 1000。

但更优雅的方案是用 cgroup v2 的 memory.max 和 memory.oom.group。给每个业务组设置内存上限,当组内内存超限时,OOM 只会在组内选择牺牲者,不会波及全局。memory.oom.group 设为 1 时,整个 cgroup 会被作为一个整体杀掉,适合那些“要么全活要么全死”的服务。

提示:调整 oom_score_adj 需要 root 权限,而且对已经在运行的进程,可以通过 echo 写入 /proc/<pid>/oom_score_adj 来动态调整。但要注意,这个值会被子进程继承,所以设之前想清楚。

4. 实操过程:从参数配置到验证的完整流程

4.1 环境准备与基线采集

在动手调之前,先采集基线数据。没有基线,你根本不知道调优有没有效果。我常用的命令组合如下:

BASH
# 采集 CPU 和内存的基线,每秒一次,共 60 次
sar -u -r 1 60 > /tmp/baseline_sar.log
 
# 查看当前的水位线和内存分布
cat /proc/zoneinfo | grep -E "Node|zone|min|low|high|free"
 
# 查看当前 cgroup 版本和挂载点
mount | grep cgroup
 
# 查看 OOM 相关参数
sysctl vm.min_free_kbytes vm.watermark_scale_factor vm.swappiness

这里重点看几个指标:%wa 是否长期高于 5%,%sy 是否高于 20%,kbmemfree 和 kbmemused 的比例,以及 pgscan_direct 和 pgsteal_direct 的增长速度。如果 pgscan_direct 在短时间内快速增长,说明 direct reclaim 很频繁,假死风险很高。

4.2 CPU 调优:cgroup v2 实战配置

假设你的系统已经挂载了 cgroup v2(现代发行版默认都是),挂载点通常是 /sys/fs/cgroup。下面是我常用的配置流程:

BASH
# 创建 critical 和 batch 两个 cgroup
mkdir -p /sys/fs/cgroup/critical
mkdir -p /sys/fs/cgroup/batch
 
# 给 critical 组高权重,batch 组低权重
echo 10000 > /sys/fs/cgroup/critical/cpu.weight
echo 100 > /sys/fs/cgroup/batch/cpu.weight
 
# 限制 batch 组的 CPU 带宽,最多用 80% 的单核时间
# 格式:$QUOTA $PERIOD,这里表示每 100ms 最多用 80ms
echo "80000 100000" > /sys/fs/cgroup/batch/cpu.max
 
# 把 SSH 服务加入 critical 组
# 先找到 sshd 的 PID,然后写入 cgroup.procs
for pid in $(pgrep sshd); do
echo $pid > /sys/fs/cgroup/critical/cgroup.procs
done
 
# 把业务进程加入 batch 组(假设业务进程名是 myapp)
for pid in $(pgrep myapp); do
echo $pid > /sys/fs/cgroup/batch/cgroup.procs
done

这里的关键是 cpu.max 的配置。80000 100000 表示在每 100ms 的周期内,batch 组最多使用 80ms 的 CPU 时间。这样即使业务进程想跑满 CPU,也会被硬性限制在 80% 以内,剩下的 20% 留给 critical 组和其他系统进程。

但要注意,cpu.max 是每个 CPU 核心的限制。如果你有 8 个核心,batch 组最多可以用 8 * 80% = 6.4 个核心的时间。如果你想让 batch 组只能用 4 个核心,应该设成 400000 100000。

注意:cgroup v2 的配置是分层的。如果你在根 cgroup 下创建了子 cgroup,子 cgroup 的权重是相对于兄弟节点计算的。所以不要把 critical 和 batch 直接放在根下,最好再建一个父 cgroup,把两者放进去,这样权重计算更清晰。

4.3 内存调优:水位线与回收参数配置

内存调优的核心是让 kswapd 提前工作,避免 direct reclaim。下面是我常用的参数配置:

BASH
# 设置 min_free_kbytes 为 1GB(根据内存大小调整)
sysctl -w vm.min_free_kbytes=1048576
 
# 设置 watermark_scale_factor 为 150
sysctl -w vm.watermark_scale_factor=150
 
# 调整 swappiness,降低交换倾向(服务器通常设 10 到 30)
sysctl -w vm.swappiness=10
 
# 调整脏页回写参数,避免一次性回写太多
sysctl -w vm.dirty_ratio=10
sysctl -w vm.dirty_background_ratio=5
 
# 持久化配置
cat >> /etc/sysctl.conf << EOF
vm.min_free_kbytes=1048576
vm.watermark_scale_factor=150
vm.swappiness=10
vm.dirty_ratio=10
vm.dirty_background_ratio=5
EOF

这里解释几个关键参数的选择理由。vm.min_free_kbytes=1048576 表示保留 1GB 的空闲内存作为缓冲。对于 16GB 内存的机器,这相当于保留 6.25% 的内存,不算多但足够让 kswapd 提前启动。vm.watermark_scale_factor=150 表示 low 水位比 min 高 1.5%,high 水位比 min 高 3%。这样 kswapd 会在空闲内存降到 min + 1.5% 时就开始回收,而不是等到 min 才被动触发。

vm.dirty_ratio=10 和 vm.dirty_background_ratio=5 是为了控制脏页回写的节奏。默认的 dirty_ratio=20 意味着系统可以积累 20% 内存的脏页,一旦触发回写,就是一次大规模的 IO 风暴,很容易导致假死。调小到 10% 和 5%,可以让回写更平滑。

4.4 OOM 保护:给关键进程上保险

OOM 保护的配置分两步。第一步是给关键进程设置 oom_score_adj:

BASH
# 保护 SSH 和 systemd
for pid in $(pgrep sshd) $(pgrep systemd); do
echo -1000 > /proc/$pid/oom_score_adj
done
 
# 给业务进程设置较高的 oom_score_adj,让它在内存不足时优先被杀
for pid in $(pgrep myapp); do
echo 500 > /proc/$pid/oom_score_adj
done

第二步是用 cgroup v2 的 memory.max 限制业务组的内存使用:

BASH
# 给 batch 组设置 8GB 内存上限
echo 8589934592 > /sys/fs/cgroup/batch/memory.max
 
# 开启 oom.group,让整个组一起被杀
echo 1 > /sys/fs/cgroup/batch/memory.oom.group
 
# 查看当前内存使用和 OOM 事件
cat /sys/fs/cgroup/batch/memory.current
cat /sys/fs/cgroup/batch/memory.events

memory.events 里的 oom 和 oom_kill 计数可以帮你判断这个组是否发生过 OOM。如果 oom_kill 持续增长,说明内存上限设得太低,或者业务有内存泄漏,需要进一步排查。

4.5 验证与压测:用 stress-ng 模拟假死场景

配置完了不能就这么算了,得验证效果。我常用 stress-ng 来模拟 CPU 和内存压力:

BASH
# 模拟 16 个 CPU 密集型进程,持续 60 秒
stress-ng --cpu 16 --timeout 60s --metrics-brief
 
# 模拟内存压力,分配 12GB 内存并持续读写
stress-ng --vm 4 --vm-bytes 3G --timeout 60s --metrics-brief
 
# 同时模拟 CPU 和内存压力
stress-ng --cpu 8 --vm 4 --vm-bytes 2G --timeout 60s --metrics-brief

在压测过程中,另开一个终端,反复执行 ssh localhost "uptime" 或者 time ls /tmp,观察响应时间。如果配置得当,即使压力很大,SSH 命令的响应时间也应该在 1 秒以内。如果超过 3 秒,说明 CPU 预留不够,需要调大 critical 组的权重或者降低 batch 组的 cpu.max。

同时用 sar -r 1 观察 pgscan_direct 的增长。如果压测期间 pgscan_direct 基本不增长,说明 kswapd 提前回收生效了,direct reclaim 被有效抑制。

5. 常见问题与排查技巧实录

5.1 假死前兆的快速识别

假死不是一瞬间发生的,通常有前兆。我整理了一份“前兆指标速查表”,你可以对照监控数据快速判断:

指标 正常范围 前兆范围 危险范围 含义
load average (1min) < 核心数 核心数 ~ 2倍 > 2倍核心数 调度队列积压
%sy < 10% 10% ~ 30% > 30% 系统态开销过大
%wa < 5% 5% ~ 20% > 20% IO 等待严重
pgscan_direct 缓慢增长 快速增长 爆发式增长 direct reclaim 频繁
kswapd 唤醒次数 偶尔 频繁 持续 内存回收压力大
D 状态进程数 0 ~ 1 2 ~ 5 > 5 不可中断睡眠堆积

如果同时出现 load 高、%sy 高、pgscan_direct 快速增长,基本可以判定系统正在走向假死,需要立即干预。

5.2 排查工具与命令组合

排查假死时,我常用的命令组合如下:

BASH
# 查看整体负载和 CPU 分布
uptime
vmstat 1 5
 
# 查看 D 状态进程
ps -eo pid,stat,comm,wchan | awk '$2 ~ /D/'
 
# 查看内存回收情况
grep -E "pgscan_direct|pgsteal_direct|allocstall" /proc/vmstat
 
# 查看水位线
cat /proc/zoneinfo | grep -A5 "Node 0, zone"
 
# 查看 cgroup 内存事件
cat /sys/fs/cgroup/batch/memory.events
 
# 查看 OOM 日志
dmesg -T | grep -i "oom\|killed process"

这里重点说 ps -eo pid,stat,comm,wchan 的用法。wchan 显示进程在内核中的等待函数,如果大量进程的 wchan 是 direct_reclaim 或 balance_dirty_pages,说明内存回收是瓶颈;如果是 rwsem_down_read 或 mutex_lock,说明有锁竞争。

5.3 独家避坑技巧

第一个坑:不要盲目调大 vm.min_free_kbytes。 我见过有人把它设成内存的 20%,结果系统可用内存大幅减少,反而更容易触发 OOM。正确的做法是根据内存大小和业务特点,设成 1% 到 5% 之间,再结合 watermark_scale_factor 微调。

第二个坑:cgroup 的 cpu.max 不要设得太死。 如果你把 batch 组的 cpu.max 设成 10000 100000(只能用 10% 的 CPU),业务可能会因为 CPU 不足而超时。我一般会先设一个宽松的值,比如 80%,然后根据压测结果逐步收紧。

第三个坑:OOM 保护不是万能的。 如果你把太多进程的 oom_score_adj 设成 -1000,当内存真的耗尽时,内核可能找不到合适的牺牲者,最终触发 panic 或者全局 OOM。我的建议是只保护最核心的 3 到 5 个进程,其他进程该杀就杀。

第四个坑:别忘了监控 PSI。 PSI(Pressure Stall Information)是内核提供的压力指标,比 load average 更直观。/proc/pressure/cpu、/proc/pressure/memory、/proc/pressure/io 分别反映 CPU、内存、IO 的压力。如果 memory 的 full 值持续高于 0,说明有进程因为内存不足而完全停滞,这是假死的明确信号。

BASH
# 查看 PSI 指标
cat /proc/pressure/cpu
cat /proc/pressure/memory
cat /proc/pressure/io

5.4 常见问题速查表

问题现象 可能原因 排查命令 解决方案
SSH 能连但命令卡 CPU 调度饥饿 vmstat 1、ps -eo stat 调大 critical 组权重
系统卡顿但 CPU 不高 direct reclaim 风暴 grep pgscan_direct /proc/vmstat 调大 min_free_kbytes
关键进程被 OOM 杀掉 oom_score 计算不利 `dmesg grep oom`
load 高但 CPU 空闲 D 状态进程堆积 ps -eo stat,wchan 排查 IO 或锁竞争
内存没满但进程被杀 cgroup 内存超限 cat memory.events 调大 memory.max
压测时响应变慢 CPU 带宽限制过严 cat cpu.stat 放宽 cpu.max

6. 监控与自愈:让系统自己扛住假死

6.1 用 PSI 做假死预警

PSI 是我目前最推荐的假死预警指标。它的原理是统计“因为资源不足而完全停滞”的时间占比。比如 /proc/pressure/memory 里的 full 值,表示所有任务都因为内存不足而停滞的时间比例。如果这个值持续大于 0,说明系统已经进入假死边缘。

我通常会在监控系统里配置这样的告警规则:

  • memory full > 0 持续 10 秒:警告
  • memory full > 0 持续 30 秒:严重
  • cpu full > 0 持续 30 秒:警告
  • io full > 0 持续 60 秒:警告

这些阈值可以根据业务特点调整,但核心思路是:PSI 的 full 值比 load average 更早、更准确地反映假死风险。

6.2 自愈脚本:压力过大时自动降级

除了监控告警,还可以写一个简单的自愈脚本,在检测到假死前兆时自动降级非关键业务。下面是一个示例:

BASH
# !/bin/bash
# /usr/local/bin/anti_freeze.sh
# 检测内存压力,如果过高则限制 batch 组的内存
 
THRESHOLD=10 # PSI full 值阈值(百分比)
BATCH_CGROUP="/sys/fs/cgroup/batch"
 
while true; do
# 读取 memory PSI 的 full 值
full=$(awk '/full/ {print $2}' /proc/pressure/memory | cut -d= -f2)
if [ "$full" -gt "$THRESHOLD" ]; then
# 降低 batch 组的内存上限,触发组内回收
current=$(cat $BATCH_CGROUP/memory.max)
if [ "$current" != "max" ]; then
new=$((current * 80 / 100))
echo $new > $BATCH_CGROUP/memory.max
logger "Anti-freeze: reduced batch memory to $new"
fi
fi
sleep 10
done

这个脚本的逻辑很简单:每 10 秒检查一次内存 PSI,如果压力超过阈值,就把 batch 组的内存上限降低 20%。这样可以强制业务组回收内存,避免全局内存耗尽。当然,这只是一个示例,实际使用时需要根据业务特点调整阈值和降级策略。

注意:自愈脚本本身也要做好保护,避免它自己成为压力源。建议把脚本放在 critical 组里,并设置合理的 oom_score_adj。

6.3 长期调优:从“防假死”到“零假死”

防假死是底线,但长期来看,我们追求的是“零假死”——系统在任何压力下都能保持可响应。这需要从架构层面做优化,比如:

  • 资源隔离:用 cgroup 或容器把不同业务隔离开,避免互相影响。
  • 容量规划:根据业务增长趋势提前扩容,不要等到资源耗尽才动手。
  • 混沌工程:定期注入 CPU、内存、IO 压力,验证系统的抗压能力。
  • 根因分析:每次假死事件后都要做复盘,找到根本原因并修复。

我在实际运维中最大的体会是:假死往往不是单一原因造成的,而是多个小问题叠加的结果。 比如一个内存泄漏的脚本 + 一个没有限制的 cgroup + 一个过低的 min_free_kbytes,单独看每个问题都不致命,但组合起来就会让系统在某个时刻突然崩溃。所以防假死调优要有全局视角,不能头痛医头。

最后分享一个小技巧:如果你不确定某个参数该设多少,可以先设一个保守值,然后用 stress-ng 压测,观察 PSI 和 pgscan_direct 的变化,再逐步调整。这个过程可能需要反复几次,但比拍脑袋设参数靠谱得多。我自己的服务器上,vm.min_free_kbytes 从默认的 64MB 调到 1GB 后,direct reclaim 的发生频率下降了 90% 以上,SSH 在压测期间的响应时间从 5 秒降到了 0.5 秒以内。这个投入产出比,值得每个运维花半小时去调。

跳出网络与文件系统:Linux CPU 与内存调优的“防假死”实战
本文聚焦Linux内核级CPU与内存调优,解决高并发场景下隐蔽的“假死”问题。核心涵盖内存水位线调控、Direct Reclaim规避、脏页刷盘优化、Swap与Overcommit策略、THP禁用与静态大页启用、NUMA内存/CPU亲和性配置,以及Kubernetes中CFS Quota限流破除等关键技术。强调通过内核参数调优消除P99/P999长尾延迟、防止OOM-Killer误杀、保障算力确定性,适用于Redis、Kafka、MySQL及K8s节点等关键基础设施。
agent问道
231
Tomcat假死与性能调优实战指南
本文深入解析Tomcat在Linux环境下因Keep-Alive、线程池容量不足及TCP超时机制冲突导致的假死现象,提出强制断开空闲连接、扩展线程池、调整OS级TCP参数三大根治方案;同时涵盖Manager熵池优化、WAR包部署规范、连接/内存泄漏防控及生产级线程池配置模板,支撑5000+ QPS高并发场景。
weixin_33796205
355
Linux 内存水位判断机制与实战调优 —— 从卡顿现象到 ftrace 定位全流程
本文围绕Linux内存水位判断机制展开,介绍了内存分配与水位判断的核心原理,包括页框分配器、Buddy System和水位线。通过医疗监护仪UI卡顿的实战用例,展示了从观察水位和碎片、perf定位热点到ftrace追踪的全流程。还给出实战优化与调参建议,如提升低阶空闲页、代码层优化和内核参数调优等。
嵌入式孙老师
1282
Linux系统下虚拟内存与物理内存的实战调优:从Swap分区设置到性能监控
本文聚焦Linux系统虚拟内存与物理内存协同机制,详解Swap分区规划(大小、文件/分区选择、多设备优先级)、核心内核参数调优(swappiness及其他关键vm.*参数)、内存监控工具链(free/meminfo/vmstat/sar)的深层解读及典型生产案例。重点阐明Swap非仅用于内存不足、swappiness的本质含义、page cache可回收性等易误解要点,面向运维与开发人员提供可落地的性能优化方法论。
晚风吻别
664
Linux 操作系统性能调优全景思维导图与生产实战精粹
本文聚焦Linux操作系统内核级性能调优,系统梳理网络协议栈、虚拟内存、文件/进程句柄、CPU调度与NUMA绑定、eBPF观测五大核心子系统在高并发生产环境中的实战优化策略。涵盖SYN队列调优、BBRv3拥塞控制、Swap禁用、Dirty Page平滑回写、句柄上限提升、NUMA节点绑定、cgroups CPU独占及零开销eBPF排障等关键技术,支撑微服务与容器化架构在大促场景下的极致稳定性与吞吐能力。
万里侯
504
Cloud Run 实战指南:从零部署到生产调优
本文深入讲解 Cloud Run 在生产环境中的实战应用,涵盖从本地开发到上线的全流程:应用改造(监听 PORT、健康检查、SIGTERM 处理)、Dockerfile 优化(使用 distroless 镜像)、Artifact Registry 区域一致性、服务账号与 IAM 安全配置。重点解析关键调优参数——并发(Concurrency)、最小/最大实例数、CPU/内存配比及流量拆分,并提供冷启动、日志结构化、数据库连接池、WebSocket 长连接等典型问题的排障方案。
Just do it
341
记录服务不可用及 JVM 调优实战
本文记录了一次服务不可用事件的排查过程,从服务假死状态入手,通过分析Linux日志、监控CPU和内存使用、JVM GC情况,发现了内存耗尽导致服务假死的问题。最终定位到大数据查询存储在session中导致内存爆满,提出了优化session管理和使用分布式session的解决方案。
贪吃的猫~
495
Linux程序卡死排查指南:5分钟定位进程假死、死循环的7种实战方法
本文系统介绍Linux环境下程序卡死(假死、死循环)的全流程排查方法:从第一现场的服务可达性和进程状态(STAT码详解)入手,结合top/htop动态监控、strace/ltrace系统调用与库函数追踪、I/O及资源瓶颈分析(文件描述符、内存、网络连接),延伸至perf性能计数器、core dump和容器化环境适配,并辅以Java死锁、Python GIL竞争、Go协程泄漏三大实战案例,强调交叉验证与自动化诊断。
782
使用jvm自带工具定位并解决java程序占用cpu高(或内存)与程序假死问题
本文介绍了如何在Linux系统中利用JVM自带工具诊断CPU占用高和程序假死问题。首先,通过top命令查看CPU占用高的进程,接着使用jps找出Java进程,并使用pidstat进行线程分析。然后,借助jstack输出线程堆栈信息,以定位问题所在。例如,通过jstack发现HoldCPUMain类的第8行可能存在问题。此外,还给出一个程序ThreadBlockMain假死的例子,其在等待输入值导致阻塞。
邢动动
3844
资深大数据架构师技术深度突围指南:从分布式底层内核、内存分配到流批一体系统级调优
本文聚焦大数据架构师核心技术突破,深入剖析分布式系统底层物理本质,涵盖Linux内核参数调优、Flink堆外内存防OOM机制、RocksDB与LSM-Tree内存博弈、Kafka零拷贝内核实现、PageCache与JVM内存协同、流批一体系统级Trade-off权衡等关键内容,强调从组件表层到操作系统/I/O/存储引擎/分布式共识的穿透式理解。
AI智能体工作室
3794
DORA 实时调优实战指南:从 `--rt` 标志到内核级抖动优化
本文系统讲解DORA机器人中间件的低抖动实时调优方法,涵盖--rt标志的内存锁定与SCHED_FIFO调度实现、Per-Node CPU亲和性配置、Linux内核级优化(performance调频器、禁用THP、PREEMPT_RT)、进程级调优(CPU绑定、实时优先级、mlockall)、systemd与容器化部署要点,以及Tokio/Zenoh运行时调优和可验证的基准测试方案。
邵瑗跃Free
163
Linux 内存多维治理:从 cgroup v2 水位线到 DAMON 与 THP 碎片化的企业级调优实战
本文聚焦Linux企业级内存调优,深入cgroup v2的PSI压力指标与memory.high/low水位线机制,解析NUMA感知调度策略,结合DAMON动态监控内存访问热力图并协同THP进行碎片整理,同时强调JVM对cgroup v2的适配及容器拓扑感知。内容覆盖内核机制、架构实践与应用协同,适用于高负载数据库与云原生场景。
谷雪_658
391
线上 Go 容器集群周期性卡顿排查:Linux cgroup CFS CPU Quota 踩限与 GOMAXPROCS 调优深度实战
本文深入剖析Kubernetes中Go容器周期性卡顿问题,核心原因为Linux CFS CPU配额(100ms周期)被Go默认GOMAXPROCS=64的多线程并发耗尽,导致高频CPU Throttling。通过动态对齐cgroup CPU quota修正GOMAXPROCS、引入uber-go/automaxprocs库、调整CFS period及协程池治理,实现Throttling率从35%降至<0.1%,P99延迟从800ms回归8ms基线。配套Prometheus监控与四大治理铁律保障云原生Go服务低抖动稳定运行。
AI智能体工作室
4642
Linux 内存碎片化与脏页平滑回写调优周度验收
本文汇报第三周Linux内核调优成果,聚焦内存碎片化治理与脏页平滑回写机制优化,覆盖伙伴系统外部碎片整理、Page Cache回写策略重构等关键技术。通过24小时高并发压测验证稳定性,并落地Ansible镜像固化与K8s Node Problem Detector自动化巡检,保障全集群内核参数一致性,支撑Kubernetes节点、Redis及数据库等云原生工作负载。
万里侯
604
Linux调优+Tomcat调优,超级干货,一定珍藏
45岁资深老架构师尼恩
890
POSIX 共享内存调优实战:消除跨进程模型权重读取的 Linux 页缓存脏页锁
本文聚焦于大模型多进程推理场景下POSIX共享内存引发的Linux内核假死问题,深入剖析信号量争抢、4KB小页导致的TLB失效与页表遍历风暴、以及Direct Reclaim级联雪崩三大瓶颈。提出通过内核vm参数调优与HugeTLB(2MB大页)替代tmpfs共享内存的终极方案,显著降低页表项数量、消除脏页锁竞争、提升TLB命中率,并给出Kubernetes中HugePages挂载与只读映射的生产实践规范。
AI客栈
164
【Linux运维】内存爆了但磁盘还有几十G?一文讲透“内存”与“磁盘”的本质区别与优化策略
本文深入剖析Linux系统中RAM(内存)与Disk(磁盘)的根本差异,指出二者功能定位不同——内存为CPU高速工作区,磁盘为持久化存储仓库,不可互换。文章通过‘办公桌vs档案室’类比阐明资源冲突表象背后的原理,并聚焦内存告警优化:重点讲解MySQL缓冲池调优、服务内存限流、Swap合理启用等软件级手段,辅以硬件扩容建议,助力小内存服务器稳定运行。
缴鸿剑Jackson
1272
Tomcat与JVM性能调优(详细)
本文详细讲解了Tomcat和JVM的性能调优,包括设置Tomcat的maxThreads、minSpareThreads、acceptCount等参数,以及JVM的内存调优和垃圾回收策略,如-Xmx、-Xms、-Xmn等,并探讨了不同垃圾收集器的选择与配置。
Java_Yhua
661
WinDbg内核调试避坑指南:解决VMware管道连接失败与系统‘假死’
本文深入解析WinDbg与VMware协同进行Windows内核调试时的五大关键问题:虚拟串口配置规范、BCD调试参数正确设置、WinDbg连接字符串精确构造、系统‘假死’的三层根因(HAL/KdCom/符号加载)及实时性能调优策略。重点涵盖管道命名规则、UEFI下bcdedit适配、超时与缓冲区调优、硬件断点优先等核心技术要点,直击83%连接失败与62%假死现象的工程根源。
bill_live
519
性能调优:思路与方向
本文深入探讨了性能调优的重要性,介绍了如何从硬件和软件层面发现性能瓶颈,并提供了详细的调优策略,包括JVM参数设置、Linux系统配置、NIO支持、数据库优化等关键点。
Jorge-z
412
SPEC CPU 介绍、测试、调优
SPEC CPU 介绍、测试、调优 SPEC CPU 介绍、测试、调优SPEC CPU 介绍、测试、调优SPEC CPU 介绍、测试、调优SPEC CPU 介绍、测试、调优
badman250
12724
通过cgroup来限制KVM虚拟机使用的cpu和内存性能调优实践
"本文主要介绍了如何使用控制群组(cgroup)来限制KVM虚拟机的CPU和内存使用,以实现性能调优。cgroup是Linux内核的一种机制,允许系统管理员精细控制进程的资源分配,提高整体效率。通过
1980
Linux性能调优指南,IBM专家资深指导
**系统调优实战**:通过具体的案例分析,展示如何在实际环境中应用上述调优技巧,解决常见的性能问题。11.
qq_34787323
593
linux性能调优.pdf
Linux性能调优是系统管理员和开发人员优化Linux系统性能的重要技能。它涉及对系统资源和应用程序的分析、监控、和调整,以实现更高的效率和响应速度。
LinuxBegin
1490
Linux简单调优与JVM参数.docx
Linux 服务器调优与 JVM 参数调优本文主要介绍了 Linux 服务器调优和 JVM 参数调优的相关知识点,以便提高服务器性能和 JVM 应用程序的运行效率。
四十五度角仰望星空
565
CPU性能调优实战:Linux核心参数与实例解析
![CPU性能调优实战:Linux核心参数与实例解析](https://img-blog.csdnimg.cn/02388d5bf9cf4e1e95d221c719e62e07.png)# 1. CPU性能调优基础概念## 1.1 CPU性能调优的重要性在IT领域,CPU是计算机的大脑,其性能直接影响整个系统的运行效率。随着技术的发展,CPU的速度和效率得到了极大的提升,但随之而来的复杂性和管理的挑战也在增加。CPU性能调优成为确保系统稳定运行和资源最优分配的关键环节。通过调优,可以有效提升服务器响应速度、处理多任务能力,以及减少资源浪费。## 1.2 性能调优的目标CPU性能调
SW_孙维
Linux系统性能调优:内存与CPU管理
# 1. Linux系统性能概述### 1.1 系统性能的影响因素在进行性能调优之前,我们首先需要了解系统性能的影响因素。系统性能受到多个因素的影响,包括但不限于以下几个方面:- 硬件资源:包括CPU、内存、磁盘、网络等硬件资源的性能和配置情况。- 软件设计与实现:系统的架构设计、算法实现、代码质量等方面对性能也有较大影响。- 系统配置与优化:包括操作系统的配置参数、进程间通信机制、文件系统的选择等。### 1.2 性能调优的重要性优化系统性能不仅可以提高用户体验,更可以提升系统的稳定性和可靠性。通过合理的性能调优,可以降低系统资源的使用率,减少系统的响应时间,提高系统
Davider_Wu
Linux调优指南
这份指南详细地为读者展开Linux性能调优的多个方面,从理论基础到实践工具,覆盖了Linux系统性能分析与优化的核心内容,是系统管理员和性能分析师的重要参考资料。
47
Linux性能调优指南:从CPU到内存,全面提升系统性能,打造高效服务器
![Linux性能调优指南:从CPU到内存,全面提升系统性能,打造高效服务器](http://www.yoramorzach.co.il/wp-content/uploads/2020/09/5G-Network-Structure.png)# 1. Linux性能调优概述**Linux性能调优是一项系统性的优化过程,旨在提高Linux系统的整体性能和响应能力。它涉及到对系统资源(如CPU、内存、文件系统和网络)进行监控、分析和优化,以最大化系统的利用率和效率。性能调优的好处包括:* 提高应用程序和系统的响应时间* 优化资源利用率,减少资源浪费* 提高系统稳定性和可靠性*
SW_孙维
Linux启动性能调优:内存管理与CPU调度优化的策略
![Linux启动性能调优:内存管理与CPU调度优化的策略](https://opengraph.githubassets.com/57b0eafbfe48175d5158a467de932ed1121006dba2b404af4c0585166fdeab0f/bittorf/calculate-linux-memory-fragmentation)# 1. Linux启动性能调优概述## 1.1 启动性能的重要性在现代计算环境中,快速的系统启动时间可以显著提高工作效率和用户体验。尤其在服务器领域,缩短启动时间有助于快速恢复服务,减少因系统故障而导致的停机时间。因此,了解Linux启
SW_孙维