直接查dmesg里的page allocation failure是最可靠方式,它反映内核页分配失败原始信号,常伴order值(如order:4对应64kb连续页),需结合overcommit_memory设置、cgroup限制、numa内存分布及/proc/pid/smaps中anonhugepages等指标综合诊断。

直接查 dmesg 里的 page allocation failure
Linux 进程内存分配失败(比如 malloc 返回 NULL、fork 失败报 Cannot allocate memory)通常不是进程自己记录的,而是内核在页分配路径上拒绝请求后写入 ring buffer 的。最可靠的方式就是翻 dmesg —— 它比 syslog 或 journalctl 更早、更全、不依赖日志服务是否启用。
执行:dmesg -T | grep -i "page allocation failure\|alloc_pages_vma\|out of memory"
- 看到
page allocation failure表示内核尝试分配物理页失败,常伴随失败阶数(如order:4对应 16×4KB=64KB 连续页),这是最原始的分配失败信号 -
alloc_pages_vma出现在 mmap 或 brk 扩展时,说明虚拟内存映射触发了底层页分配失败 - 如果同时出现
Out of memory,说明已触发 OOM killer,此时分配失败是结果而非原因
区分是全局内存不足还是局部限制
分配失败不等于系统没内存。常见干扰项包括:overcommit_memory=2 下虚拟地址空间耗尽、cgroup memory limit 到顶、NUMA node 本地内存枯竭。
检查关键点:
PyCharm 2026.2.0.1 Linux版提供 JetBrains 官方 2026.2.0.1 版本安装包,适合需要指定 PyCharm 版本进行 Python 项目开发、运行和调试的用户。
- 看
/proc/sys/vm/overcommit_memory:值为2时,CommitLimit和Committed_AS差值小于申请量就会失败,和free显示的空闲无关 - 查 cgroup 限值:
cat /sys/fs/cgroup/memory/$(ps -o cgroup= -p <pid>)</pid>下的memory.limit_in_bytes和memory.usage_in_bytes - NUMA 不均:
numastat -p <pid></pid>看跨 node 分配比例;cat /sys/devices/system/node/node*/meminfo | grep MemFree看各 node 是否有明显空闲差异
从 /proc/pid/smaps 找隐性失败诱因
有些“分配失败”其实发生在用户态 malloc 层,但根源是内核无法满足大页或特定对齐需求。这时 /proc/<pid>/smaps</pid> 里藏着线索:
- 搜
AnonHugePages::单个进程 >1GB 可能导致普通页碎片化,后续小分配失败 - 看
MMUPageSize:和MMUHugePageSize::若进程启用了 2MB 大页但物理内存不连续,mmap(MAP_HUGETLB)会静默失败 - 查
SwapPss:高但SwapCached:低:说明 swap 回收卡住,page reclaim 无法释放 anon pages,间接抬高分配门槛
别信 ps 或 top 的 RSS,要盯 VmData 和 VmStk
很多分配失败发生在堆(brk)或栈(expand_stack)扩展时,但 ps 的 RSS 或 top 的 RES 只反映已驻留页,不体现“即将扩展却失败”的意图。
真正该看的是:
-
VmData:(来自/proc/<pid>/status</pid>)—— 数据段大小,brk扩展目标,持续增长逼近RLIMIT_DATA就容易失败 -
VmStk:—— 栈大小,ulimit -s限制下递归过深或大局部数组会直接Segmentation fault,而非返回错误 -
cat /proc/<pid>/limits | grep data</pid>和stack,确认软硬限制是否被设得太紧
真实场景里,malloc 失败往往发生在 VmData 接近 limit 且内核又无法回收足够页的时候——这两个指标必须一起看,缺一不可。










