Linux系统 "Cannot allocate memory"错误处理文档

SSH远程登录一台服务器时,报如下错误:-bash: fork: Cannot allocate memory

"Cannot allocate memory" (无法分配内存)这个错误信息虽然看起来是内存不足,但在 Linux 系统中,它可能是由两种截然不同的情况引起的:真正的物理内存耗尽,或者更常见的系统进程数达到上限。处理前,需要先判断是哪种情况。

第一步:快速诊断,定位问题根源

出现这种情况,主要是因为进程跑满了,memory被消耗光了,无法为其他的操作。

首先,登录到出问题的服务器,执行两个快速检查命令,来判断是哪种情况。

检查内存使用情况:

free -h

重点关注 available (可用内存) 这一列。如果这个值很低(比如持续低于总内存的10%),并且 Swap 分区也有使用,那很可能是物理内存真的不足了。

问题原因:

[root@localhost ~]# ssh 10.0.242.13
root@10.0.242.13's password: 
Last login: Fri Dec  9 15:14:51 2022 from 100.100.105.29
-bash: fork: Cannot allocate memory
-bash-4.2# df -Th
-bash: fork: Cannot allocate memory
......

检查系统进程数:

查看最大进程数
# sysctl kernel.pid_max
查看进程数
# ps -eLf | wc -l
如果当前进程数非常接近或已经超过了 kernel.pid_max 的值,那问题就出在进程数限制上。这是导致该错误的一个常见且容易被忽略的原因

第二步:根据诊断结果,采取对应措施

情况一:进程数超限(最常见原因之一)

临时设置(重启后失效):

# 将 99999 替换为你想要设置的数值
sudo sysctl -w kernel.pid_max=99999

永久设置(推荐):

# 将配置写入系统文件
echo "kernel.pid_max=99999" | sudo tee -a /etc/sysctl.conf
# 使配置立即生效
sudo sysctl -p

# 注意:64位系统的 kernel.pid_max 最大值可以设置到 2^22(约419万)。调整后,错误应该会立即消失。

情况二:物理内存不足

如果 free -h 显示系统确实没有可用内存了,就需要进一步排查是谁占用了内存。

找出内存消耗大户:使用以下命令,可以列出内存占用最高的前10个进程

ps aux --sort=-%mem | head -n 10

根据进程类型采取措施:

如果是异常或未知进程:确认它不是关键业务进程后,可以尝试终止它。

# 先尝试安全终止 (PID替换为实际进程ID)
sudo kill -15 <PID>
# 如果无效,再强制终止
sudo kill -9 <PID>

如果是核心业务进程(如 Java 应用):这通常意味着当前服务器配置已无法满足业务需求。可以考虑:

  • 升级服务器内存配置。

  • 优化应用程序。例如,如果是 Java 应用,可以使用 jvisualvm、jmap 等 JDK 自带工具分析堆内存,定位是否存在内存泄漏,或优化对象创建逻辑。

其他可能原因:

  • 内存碎片化:如果总内存看起来还够,但大块连续内存不足,也可能导致分配失败。可以尝试整理内存碎片

sudo echo 1 > /proc/sys/vm/compact_memory
  • Huge Pages 配置不当:如果系统为“大页内存”预留了过多内存,可能导致常规内存不足。可以检查并调整 /etc/sysctl.conf 中的 vm.nr_hugepages 配置。

针对 Java 应用的特殊情况

如果你的程序是 Java 应用,除了系统内存,还需要考虑 JVM 自身的限制。

  • 堆内存不足:会抛出 java.lang.OutOfMemoryError: Java heap space。这通常需要通过 -Xmx 参数增加最大堆内存,或使用内存分析工具(如 Eclipse MAT)检查是否存在内存泄漏。

  • 本地内存不足:JVM 自身、线程栈、元空间等也消耗内存。如果这些区域设置不当(如线程数过多),也可能触发系统的 "Cannot allocate memory" 错误

posted @ 2022-12-09 16:11  梦徒  阅读(2308)  评论(0)    收藏  举报