Python os.fork OSError: [Errno 12] 无法分配内存(但内存并非问题)

13 投票
2 回答
7350 浏览
提问于 2025-04-18 07:21

我遇到的问题和这个很像:Python subprocess.Popen "OSError: [Errno 12] Cannot allocate memory"

我有一个后台进程,它运行得还不错,能持续几分钟,但之后通过 popen2.Popen3() 执行 shell 程序时就失败了。这个进程会生成 20 个线程。看起来内存不是问题,因为这台机器上只有这个程序在运行,内存有 2G,但它使用的不到 400M。我一直在记录 ru_maxrss,发现它只有 50M(在 OSError 报错前后都是这样)。

ulimit -a:

core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 15962
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 15962
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

我还在运行时监控 free -mls /proc/$pid/fd | wc -l,这两个命令都没有显示资源耗尽的迹象。下面是运行时的典型 free -m 输出:

             total       used       free     shared    buffers     cached
Mem:          2003        374       1628          0         46        154
-/+ buffers/cache:        173       1830
Swap:          283          0        283

... 文件描述符的数量大约在 90 到 100 之间。

主机是 Ubuntu 12.04(服务器 jeos - 最小化虚拟机),使用 Python 2.7.3,在 VMWare 主机上运行。

所以我在想:接下来我该怎么做才能诊断出为什么会失败呢?有没有其他的资源统计信息可以收集?我需要深入到 strace 的层面吗?

2 个回答

1

检查一下你的硬盘空间是否用完了,这就是我遇到的问题。

bravo@by1-dotbravo-01:~$ df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda1              16G   16G     0 100% /
tmpfs                 2.0G     0  2.0G   0% /dev/shm
/dev/sdb              296G  162G  119G  58% /home
2

假设:如果你的虚拟机是32位的,可能会遇到地址空间不足的问题。

这里说的不是内存,而是地址空间。让我来解释一下:在Linux系统中,很多东西(比如输入输出、显卡、内存映射文件)会占用地址空间,但不一定会消耗相应数量的主内存。

下面是一些相关问题的解释:

http://us.download.nvidia.com/XFree86/Linux-x86/331.89/README/knownissues.html

(可以查找“X86平台上的内核虚拟地址空间耗尽”这一部分,使用 dmesg 命令来测试是否存在这种情况)

如果在使用 mmap 时出现 ENOMEM 错误,这很可能意味着“地址空间不足”,而不仅仅是“内存不足”。不过,我不太确定在CPython中如何诊断这个问题。如果你的系统上有一些大文件被任何正在运行的进程 mmap 了,那就要注意了……

撰写回答