【问题标题】:High memory usage with Pythons native tarfile libPythons 本机 tarfile 库的高内存使用率
【发布时间】:2014-01-29 04:04:35
【问题描述】:

我在内存受限的环境中工作,并使用带有 tarfile 库 (http://docs.python.org/2/library/tarfile.html) 的 Python 脚本来持续备份日志文件。

随着日志文件数量的增加(~74 000),我注意到系统现在运行时有效地终止了这个备份进程。我注意到它消耗了大量内存(在被操作系统杀死之前大约 192mb)。

我可以将日志文件制作成 gzip tar 存档 ($ tar -czf),不会出现问题或内存占用过高。

代码:

import tarfile
t = tarfile.open('asdf.tar.gz', 'w:gz')
t.add('asdf')
t.close()

目录“asdf”包含 74407 个文件名长度为 73 的文件。 当你有大量文件时,不建议使用 Python 的 tarfile 吗?

我正在运行 Ubuntu 12.04.3 LTS 和 Python 2.7.3(tarfile 版本似乎是“$Revision: 85213 $”)。

【问题讨论】:

  • 我们不知道你是如何使用它的。
  • AFAIK tarfile 是一个纯 python 模块,因此它可能tar 命令消耗更多的内存也就不足为奇了。
  • 你能告诉我们你的代码吗?发生这种情况的原因可能有很多,根据文档,当以流模式打开时,TarFile 类以 ~(20 * 512) 字节的块处理其数据。您是否打开了随机访问? (docs.python.org/2/library/tarfile.html)。
  • 在您的情况下,使用二进制 tar 而不是 Python tar 模块,您实际上可能会更好。
  • @IgnacioVazquez-Abrams 我用一些代码更新了这个问题,但它实际上只是基本的标准代码。添加了一些文件数量和文件名长度的规范。如果这很重要......

标签: python tarfile


【解决方案1】:

两种解决方法:如果你的虚拟机没有swap添加试试。我有 13GB 的文件要打包成一个大包,但它一直在失败。操作系统被杀死。添加 4GB 交换空间有帮助。

如果您使用的是 k8-pod 或 docker 容器,一种快速的解决方法可能是 - 在 host 中添加交换,capability:sys-admin 或特权模式将使用主机交换。

如果您需要带有流的 tarfile 以避免内存 - 结帐:https://gist.github.com/leth/6adb9d30f2fdcb8802532a87dfbeff77

【讨论】:

    【解决方案2】:

    我在源代码中进行了一些挖掘,似乎 tarfile 将所有文件存储在 TarInfo 对象列表 (http://docs.python.org/2/library/tarfile.html#tarfile.TarFile.getmembers) 中,导致内存占用不断增加,文件名很多且很长。

    这些 TarInfo 对象的缓存似乎在 2008 年的提交中得到了显着优化,http://bugs.python.org/issue2058,但据我所知,它仅与 Python 3 的 py3k 分支合并。

    可以一次又一次地重置成员列表,就像http://blogs.it.ox.ac.uk/inapickle/2011/06/20/high-memory-usage-when-using-pythons-tarfile-module/ 一样,但是我不确定当时错过了什么内部 tarfile 功能,所以我改用系统级调用 (> os.system('tar -czf asdf.tar asdf/')。

    【讨论】:

    猜你喜欢
    • 2019-07-29
    • 1970-01-01
    • 2013-09-16
    • 2015-06-03
    • 2011-09-19
    • 2018-07-01
    • 1970-01-01
    • 2012-05-31
    • 1970-01-01
    相关资源
    最近更新 更多