商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 系统应用 > Linux如何查看具体的进程内存分配失败导致的系统挂起记录

Linux如何查看具体的进程内存分配失败导致的系统挂起记录

  发布于2026-08-22 阅读(0)

扫一扫,手机访问

答案是:需执行dmesg -T | grep -i "page allocation failure|low memory|watermark"查找关键信号,再结合/proc/pid/stack确认进程是否卡在__alloc_pages_slowpath等内核分配路径。

Linux如何查看具体的进程内存分配失败导致的系统挂起记录

查 dmesg 里有没有 “page allocation failure”

进程未被杀掉,也未报错,却卡住不动,这种“挂起”现象通常并非进程自身停止,而是内核在分配内存时遭遇失败,进而陷入等待或重试状态,最终致使进程僵死。最直接的证据存在于内核环缓冲区。其中,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 值越大,说明需要的连续物理页越长,越容易失败(尤其在内存碎片严重时)
  • mode 字段里的 GFP_ATOMICGFP_NOWAIT 表示该分配不能睡眠,失败即阻塞,不抛异常也不返回
  • 没有 Killed process 不代表安全,可能只是还没轮到 kill,或者进程卡在分配路径上没机会被选中

看 /proc/[pid]/stack 确认进程是否卡在内存分配栈

找到疑似挂起的进程 PID 后,直接读它的内核调用栈:
cat /proc/12345/stack
如果输出里反复出现 __alloc_pages_slowpathwait_event_killabletry_to_free_pages,基本可以断定它正卡在内存分配或回收路径上。

常见卡点:

  • __alloc_pages_nodemask → __alloc_pages_slowpath → wait_event_killable:等待内存回收完成,但回收迟迟无法释放足够页
  • shrink_slab → shrink_node → shrink_page_list:正在尝试回收 slab 或页面,但压力太大收不回来
  • 空栈或只有一行 [<0000000000000000>] 0x0:进程处于不可中断状态(D 状态),通常就是卡在上述内核路径里

用 vmstat 和 pidstat 捕捉分配失败前的内存压力信号

单纯查日志是回溯,要提前预警得靠实时指标。重点盯三个信号:

  • vmstat 1 中的 pgpgin/pgpgout 持续飙升,且 pgmajfault > 100/s:说明频繁缺页,已在透支 page cache
  • pidstat -r 1 显示某进程 %mem 稳定但 VSZ 暴涨、RSS 不涨:可能是 mmap 大块地址空间但未实际分配物理页,一旦 touch 就卡住
  • cat /proc/zoneinfo | grep -A5 "Node [0-9] DMA|Normal|HighMem" 中的 pagesetsfree 接近 0,且 low watermark 被持续击穿:内核已进入紧急回收模式

这些不是“失败记录”,而是失败前几秒的确定性征兆。真等到 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 就有可能把这些信息给丢弃啦。

验证方式:
dmesg | head -n 20 | grep -o "level=[0-9]" 查看实际日志等级
grep -r "level.*4" /etc/rsyslog.conf /etc/rsyslog.d/ 看是否配置了接收 WARNING 级别

所以别在 journalctl 里白费时间搜这个关键词,dmesg -T 才是第一现场。

本文转载于:https://www.php.cn/faq/3029505.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

产品推荐

热门关注