当前位置:首页>Linux>Linux休眠与挂起(上)——suspend/hibernate原理排查

Linux休眠与挂起(上)——suspend/hibernate原理排查

  • 2026-10-11 07:10:59
Linux休眠与挂起(上)——suspend/hibernate原理排查

大家好,我是冯哥的缓存。今天聊一个很多 Linux 用户绕不开的话题:合盖睡眠、休眠唤醒不了、开机比重启慢。

suspend 和 hibernate 到底有什么区别?

很多人不知道 Linux 其实有四种"睡眠"状态,Windows 的"睡眠"和"休眠"只是其中两种。

状态
英文名
中文习惯叫法
内存数据
硬盘写入
断电后能恢复?
唤醒速度
S1/S2
Suspend to Idle
浅度挂起
保留在内存
不写
❌ 不能
秒级
S3
Suspend to RAM
挂起(睡眠)
保留在内存
不写
❌ 不能
1-3秒
S4
Suspend to Disk
休眠
写入 swap
全部写入
✅ 能
10-30秒
S3+S4
Hybrid Sleep
混合睡眠
同时保留内存+写入
写入
✅ 能
秒级(内存在时)

💡 提示: 大多数人说的"合盖睡眠"是 S3(Suspend to RAM)——内存通电保持数据,其他硬件断电,功耗极低。说的"休眠"是 S4(Suspend to Disk)——内存内容写进硬盘 swap 分区,完全断电,下次开机从硬盘恢复。

Linux 休眠的底层架构

Linux 的休眠功能由多个层级协同完成,理解这个架构能帮你快速定位问题在哪一层。

层级
组件
职责
问题定位
应用层
systemd-logind / upower
处理合盖、按电源键等事件
服务层
systemd sleep target
协调挂起流程,暂停服务
内核层
kernel PM subsystem
控制 ACPI 电源状态
整个挂起失败
固件层
BIOS/UEFI ACPI
实际断电/通电硬件
唤醒后黑屏
驱动层
各硬件驱动
支持 suspend/resume 回调
唤醒后硬件不工作

⚠️ 注意: 休眠失败通常发生在"驱动层"——某个硬件的驱动不支持 suspend/resume,导致整个链条卡住。显卡驱动(尤其是 NVIDIA 闭源驱动)是最常见的罪魁祸首。

第一步:确认你的系统支持哪些睡眠状态

在终端运行这条命令,看看你的硬件实际支持什么:

cat /sys/power/state

常见输出示例:

输出内容
说明
freeze mem disk
支持浅度挂起(S1)、S3挂起、S4休眠
freeze mem
不支持 S4 休眠(swap 未配置或 BIOS 不支持)
freeze
只支持最浅度挂起,休眠相关功能有限

再确认 S3 挂起模式(有些新硬件默认用 s2idle 而不是 deep):

cat /sys/power/mem_sleep

输出
说明
[s2idle] deep
当前用 s2idle(浅度),可切换到 deep
s2idle [deep]
当前用 deep(推荐,真正的 S3)
只有 s2idle
硬件或 BIOS 不支持 S3 deep

💡 提示: 方括号 [ ] 内的模式是当前使用的模式。如果发现当前是 [s2idle],可以尝试切换到 deep 模式,很多"挂起耗电快"的问题就是因为用的是 s2idle 而不是真正的 S3。

第二步:确认休眠(S4)所需的 swap 配置

S4 休眠必须把内存内容写进 swap,所以:

# 查看 swap 配置
free -h
# 或
swapon --show

场景
swap 要求
休眠(S4)
swap 容量 ≥ 内存大小(8GB内存需要≥8GB swap)
挂起(S3)
不需要 swap
混合睡眠
同 S4

⚠️ 注意: 很多人安装 Linux 时选了"自动分区",swap 分区只有 2GB 甚至没有,这时候 S4 休眠无法工作,下篇会聊到如何用 swapfile 补救。

第三步:查看 systemd 的睡眠配置

systemd 控制着合盖、按电源键等事件的响应行为:

# 查看 logind 的电源管理配置
cat /etc/systemd/logind.conf | grep -v "^#" | grep -v "^$"

关键配置项含义:

配置项
默认值
说明
HandleLidSwitchsuspend
合盖时挂起
HandleLidSwitchExternalPowersuspend
接电源合盖时挂起
HandlePowerKeypoweroff
按电源键关机
HandleSuspendKeysuspend
按挂起键挂起
HandleHibernateKeyhibernate
按休眠键休眠

💡 提示: 如果你想合盖不挂起(比如接了外接显示器),把 HandleLidSwitch=ignore 写进 /etc/systemd/logind.conf,然后 sudo systemctl restart systemd-logind 即可。

第四步:手动测试挂起和休眠

测试休眠前,先确认 swap 足够,否则系统可能会直接关机。先手动触发,比等系统自动挂起更容易定位问题:

# 测试 S3 挂起(几秒后按任意键唤醒)
sudo systemctl suspend

# 测试 S4 休眠(需要 swap 配置正确)
sudo systemctl hibernate

# 测试混合睡眠
sudo systemctl hybrid-sleep

⚠️ 注意: 测试休眠时确保已保存所有工作!S4 休眠会把内存写进硬盘,过程中系统完全断电,如果恢复失败会相当于直接关机。

第五步:读取日志定位失败原因

挂起/唤醒失败后,最重要的是看日志:

# 查看最近一次挂起相关的日志
journalctl -b 0 | grep -i "suspend\|hibernate\|sleep\|wake\|pm:"

# 只看系统上次唤醒后的日志
journalctl -b -1 | tail -100

# 查看内核电源管理日志(更底层)
sudo dmesg | grep -i "PM\|suspend\|resume\|wake"

常见错误关键词速查:

日志关键词
含义
PM: Some devices failed to suspend
有设备驱动不支持 suspend
nvidia: failed to suspend
NVIDIA 驱动挂起失败(最常见)
ACPI: Waking up from system sleep state S3
S3 唤醒成功
PM: Basic memory bitmaps free
S4 休眠进度日志
Failed to hibernate: Not enough storage
swap 不够大
i915: resume failed
Intel 核显驱动唤醒失败
rtcwake:
定时唤醒相关

第六步:确认哪个设备阻止了挂起

# 查看哪些设备"阻止"了挂起
cat /proc/driver/rtc   
systemctl list-units --state=active | grep sleep

# 更直接:查看 wakeup 相关设备
cat /proc/acpi/wakeup

还有一个很有用的命令,可以看到有哪些程序持有"唤醒锁":

# 查看所有电源管理抑制器(谁不让睡)
systemd-inhibit --list

常见的"阻止睡眠"程序:

程序
阻止原因
正在下载(浏览器/下载器)
下载中不休眠
虚拟机运行中(VirtualBox/VMware)
虚拟机持有唤醒锁
媒体播放(VLC/mpv)
播放中防息屏
正在备份(Déjà Dup)
备份中不休眠

各桌面环境的休眠管理界面

不同桌面环境的电源管理设置入口不同:

桌面环境
图形设置路径
命令行工具
GNOME
设置 → 电源
gsettings
KDE
系统设置 → 电源管理
powerdevil
Xfce
设置 → 电源管理
xfce4-power-manager
LXDE/LXQt
首选项 → 电源管理
lxsession
无桌面/i3
手动配置
systemctl suspend

💡 提示: GNOME 默认设置里没有休眠(hibernate)按钮,它被故意隐藏了,因为 GNOME 团队认为休眠功能不够稳定。如果你想在电源菜单里加上休眠按钮,需要安装扩展或修改配置。如果 GNOME 版本不同,也可以用 gnome-control-center power 直接从终端打开。

快速诊断流程

步骤
命令
看什么
1. 确认支持的状态
cat /sys/power/state
有没有 mem 和 disk
2. 确认 S3 模式
cat /sys/power/mem_sleep
是否是 [deep]
3. 确认 swap
free -h
swap 够不够大
4. 手动触发测试
sudo systemctl suspend
能否挂起和唤醒
5. 查日志
journalctl -b 0 | grep -i suspend
有无 failed 报错
6. 查阻止者
systemd-inhibit --list
有无程序阻止

常见报错速查

报错现象
可能原因
快速定位命令
合盖无反应
logind 配置问题
cat /etc/systemd/logind.conf
挂起后无法唤醒
驱动不支持 resume
journalctl -b -1 | grep -i resume
唤醒后黑屏
显卡驱动问题
sudo dmesg | grep -i "nvidia|i915|drm"
hibernate 命令报错
swap 未配置或不够
swapon --show
挂起后几秒自动唤醒
网卡唤醒功能(Wake on LAN)
cat /proc/acpi/wakeup
只有 s2idle 没有 deep
硬件/BIOS 不支持 S3
BIOS 里找 Sleep State 设置
唤醒后 Wi-Fi 断开
Wi-Fi 驱动 resume 有 bug
下篇会讲解决方法

小结

知识点
要记的内容
四种睡眠状态
S3=挂起(内存保电),S4=休眠(写入硬盘)
S3 要求
硬件+驱动支持 suspend/resume
S4 要求
swap 容量 ≥ 内存大小
问题排查
journalctl -b 0 | grep suspend
 看日志
阻止者排查
systemd-inhibit --list
 看谁不让睡
GNOME 没休眠按钮
正常,需要额外配置才会出现

💡 下篇预告: 实战修复:swap 不足怎么补、怎么切换 S3 deep 模式、NVIDIA 休眠黑屏怎么处理、GNOME 怎么加休眠按钮、Wi-Fi 唤醒后断线怎么解决。

最新文章

随机文章