答案是:先执行dmesg -T | grep -i "page allocation failure|low memory|watermark"定位关键内核信号,再结合/proc/pid/stack确认目标进程是否阻塞在__alloc_pages_slowpath等内存分配路径中,从而排查 Linux 进程内存分配失败引发的系统挂起问题。

查 dmesg 里有没有 “page allocation failure”
如果进程没有被直接杀掉,也没有明显报错,却一直卡住不响应,这类“挂起”现象通常并不是应用自身停止运行,而是 Linux 内核在申请内存时发生失败,随后进入等待、回收或重试流程,最终让进程看起来像僵死一样。最直接、最有价值的排查线索就在内核环形缓冲区中。其中,page allocation failure 是最关键的日志信号,它通常比 Out of memory 出现得更早,也更能说明“内存分配失败导致进程挂起”这一根本原因。
执行:dmesg -T | grep -i "page allocation failure|low memory|watermark"
如果看到类似:
[Tue Jul7 23:41:02 2026] lowmemorykiller: Killing 'ja va' (12345), adj 0, to free 12345kB on node 0 [Tue Jul7 23:41:02 2026] page allocation failure: order:4, mode:0x140cca
这说明内核已经无法满足连续 2^4=16 页的物理内存分配请求。按默认页大小 4KB 计算,也就是 64KB 的连续页申请失败,系统此时通常会触发内存回收,严重时甚至直接 kill 进程。但在某些分配场景下,例如 GFP_ATOMIC 上下文,内核连 kill 都来不及执行,进程就可能直接卡在 __alloc_pages_slowpath 这条慢速分配路径上。
order值越大,表示需要的连续物理页越多,分配失败的概率越高,尤其是在内存碎片严重的 Linux 服务器上更常见mode字段中如果包含GFP_ATOMIC或GFP_NOWAIT,通常表示这次内存分配不能睡眠等待,失败后更容易出现阻塞、卡顿或无明显异常返回- 即使日志中没有出现
Killed process,也不代表系统安全,可能只是还没执行到 kill,或者进程已经卡死在内存分配路径上,根本没有机会进入后续处理
看 /proc/[pid]/stack 确认进程是否卡在内存分配栈
找到疑似挂起的进程 PID 之后,最直接的办法就是查看它的内核调用栈:cat /proc/12345/stack
如果输出中反复出现 __alloc_pages_slowpath、wait_event_killable、try_to_free_pages 这些函数,基本就可以判断该进程正卡在 Linux 内存分配或内存回收路径上。
常见卡点包括:
__alloc_pages_nodemask → __alloc_pages_slowpath → wait_event_killable:说明进程正在等待内存回收完成,但系统迟迟回收不到足够可用页shrink_slab → shrink_node → shrink_page_list:说明内核正尝试回收 slab 或页面缓存,但当前内存压力过大,回收效率不足- 空栈,或只看到一行
[<0000000000000000>] 0x0:通常表示进程处于不可中断的 D 状态,这类情况往往也与上述内核内存路径阻塞有关
用 vmstat 和 pidstat 捕捉分配失败前的内存压力信号
仅仅查看日志更适合事后回溯;如果想提前发现 Linux 内存不足或内存分配失败风险,就需要结合实时监控指标。重点关注以下三个信号:
vmstat 1中的pgpgin/pgpgout持续升高,同时pgmajfault> 100/s:说明系统频繁发生缺页,大量消耗 page cache,内存压力已经明显上升pidstat -r 1显示某个进程%mem基本稳定,但VSZ快速增长、RSS却没有同步上涨:这通常意味着进程通过mmap申请了大块虚拟地址空间,却尚未真正映射为物理页,一旦实际访问这些内存,就可能触发卡顿甚至挂起cat /proc/zoneinfo | grep -A5 "Node [0-9] DMA|Normal|HighMem"中pagesets下的free接近 0,同时lowwatermark 持续被击穿:说明内核已经进入紧急内存回收阶段,后续很容易出现page allocation failure
这些指标本身不是“内存分配失败记录”,但往往是失败发生前几秒最明确、最稳定的预警信号。很多时候,等到 page allocation failure 真正出现在日志里,系统实际上已经处在高风险状态了。
注意 /var/log/messages 里没有对应记录是正常的
需要注意的是,排查这类问题时,dmesg 往往才是最可靠的第一手信息来源。像 /var/log/messages 或 journalctl,很多情况下并不会完整记录 page allocation failure 这类底层内核告警。原因在于,它们默认可能会过滤掉 kernel log level 小于 3 的消息,也就是低于 KERN_ERR 的日志。而 page allocation failure 常见级别通常是 KERN_WARNING(level 4)。dmesg 会直接展示内核缓冲区中的完整内容,但 rsyslog 或其他日志组件却有可能把这些 warning 级别信息过滤掉。
验证方式:dmesg | head -n 20 | grep -o "level=[0-9]" 查看实际日志等级grep -r "level.*4" /etc/rsyslog.conf /etc/rsyslog.d/ 检查是否配置了接收 WARNING 级别日志
因此,不要只在 journalctl 或 /var/log/messages 中反复搜索这个关键词,真正排查 Linux 内存分配失败、系统挂起和进程卡死问题时,dmesg -T 才是最关键的排查入口。
