Python os.fork OSError: [Errno 12] 无法分配内存(但内存并非问题)
我遇到的问题和这个很像: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 -m
和 ls /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 个回答
检查一下你的硬盘空间是否用完了,这就是我遇到的问题。
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
假设:如果你的虚拟机是32位的,可能会遇到地址空间不足的问题。
这里说的不是内存,而是地址空间。让我来解释一下:在Linux系统中,很多东西(比如输入输出、显卡、内存映射文件)会占用地址空间,但不一定会消耗相应数量的主内存。
下面是一些相关问题的解释:
http://us.download.nvidia.com/XFree86/Linux-x86/331.89/README/knownissues.html
(可以查找“X86平台上的内核虚拟地址空间耗尽”这一部分,使用 dmesg
命令来测试是否存在这种情况)
如果在使用 mmap
时出现 ENOMEM
错误,这很可能意味着“地址空间不足”,而不仅仅是“内存不足”。不过,我不太确定在CPython中如何诊断这个问题。如果你的系统上有一些大文件被任何正在运行的进程 mmap
了,那就要注意了……