Python IOError无法分配内存,尽管内存很多

2024-09-26 21:26:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我编写了一个基本程序来检查包含许多jpeg文件(500000+)的目录树 确认它们没有损坏(大约有3-5%的文件似乎在某种程度上损坏了),然后取一份文件(即使是损坏的文件)并将信息保存到数据库中。在

有问题的jpeg文件位于windows系统上,并通过cifs装载在linux机器上。它们的大小大多在4兆字节左右,尽管有些可能稍大或稍小。在

当我运行这个程序时,它似乎运行得相当好,然后它就崩溃了,出现了下面的错误。这是在它处理了大约1100个文件之后(错误表明,在试图打开一个4.5 meg的文件时出现了问题)。在

现在我知道我可以捕捉到这个错误并继续或重试等等,但是我很好奇为什么它会首先发生,如果捕捉和重试真的能解决问题-或者它会仅仅停留在重试中(当然,除非我限制了重试,但是会跳过一个文件)。在

我在debian系统上使用“Python2.7.5+”来运行这个。系统至少有4Gig(可能是8)的ram,top报告说,脚本在任何时候运行时使用的ram少于1%,cpu的使用率低于3%。类似地,这个脚本运行的jpeginfo也使用同样少的内存和cpu。在

{我用另一种方法来避免在给定的内存中读取过多的文件

您还可以注意到“jpeginfo”命令在while循环中寻找“[OK]”响应。 这是因为如果“jpeginfo”认为找不到该文件,它将返回0,因此它不会被视为错误状态subprocess.check_输出打电话。在

我想知道jpeginfo在第一次尝试时似乎找不到某些文件这一事实是否有关联(我怀疑是这样),但返回的错误是cannot allocate memory,而不是file not found。在

错误:

Traceback (most recent call last):
  File "/home/m3z/jpeg_tester", line 95, in <module>
    main()
  File "/home/m3z/jpeg_tester", line 32, in __init__
    self.recurse(self.args.dir, self.scan)
  File "/home/m3z/jpeg_tester", line 87, in recurse
    cmd(os.path.join(root, name))
  File "/home/m3z/jpeg_tester", line 69, in scan
    with open(filepath) as f:
IOError: [Errno 12] Cannot allocate memory: '/path/to/file name.jpg'

完整程序代码:

^{pr2}$

Tags: 文件inself程序脚本home系统错误
1条回答
网友
1楼 · 发布于 2024-09-26 21:26:26

在我看来,Python只是从底层的open()调用传递了一个错误,而真正的罪魁祸首是Linux CIFS支持-我怀疑Python会合成ENOMEM,除非系统内存真的耗尽了(而且可能即使这样,我也希望调用Linux OOM killer,而不是获取{})。在

不幸的是,它可能需要一些Linux文件系统专家来弄清楚那里到底发生了什么,但是看看sources for CIFS in the Linux kernel,我可以看到当各种内核特定的资源耗尽而不是系统内存总量时,ENOMEM会返回很多地方,但是我对它还不太熟悉,不知道它们有多可能。在

要排除特定于Python的任何内容,可以在strace下运行该进程,这样就可以看到Python从Linux获得的确切返回代码。为此,请运行以下命令:

strace -eopen -f python myscript.py myarg1 myarg2 2>strace.log

-f将跟随子进程(即您运行的jpeginfo命令),而-eopen将只显示open()调用,而不是所有系统调用(默认情况下,strace就是这样做的)。这可能会生成合理数量的输出,这就是为什么我在上面的示例中将其重定向到一个文件,但是如果您愿意,可以让它显示在您的终端上。在

我希望你在得到例外之前会看到这样的情况:

^{pr2}$

如果是这样的话,这个错误直接来自于文件系统open()调用,而在Python脚本中对此几乎无能为力。如果jpeginfo失败,您可以捕捉异常并重试(可能在短暂的延迟之后),但是如果不知道首先是什么导致了错误,很难说这个策略会有多成功。在

当然,您可以在本地复制这些文件,但这听起来会很痛苦,因为文件太多了。在

编辑:作为旁白,您将看到许多与脚本无关的open()调用,因为strace正在跟踪Python发出的每一个调用,其中包括它打开自己的.py.pyc文件。忽略那些与你感兴趣的文件无关的文件。在

相关问题 更多 >

    热门问题