我有一个 Python 实用程序,它遍历一个tar.xz
文件并处理每个单独的文件。这是一个 15MB 的压缩文件,包含 740MB 的未压缩数据。
在一台内存非常有限的特定服务器上,程序由于内存不足而崩溃。我使用objgraph来查看创建了哪些对象。事实证明,这些TarInfo
实例没有被释放。主循环与此类似:
with tarfile.open(...) as tar:
while True:
next = tar.next()
stream = tar.extractfile(next)
process_stream()
iter+=1
if not iter%1000:
objgraph.show_growth(limit=10)
输出非常一致:
TarInfo 2040 +1000
TarInfo 3040 +1000
TarInfo 4040 +1000
TarInfo 5040 +1000
TarInfo 6040 +1000
TarInfo 7040 +1000
TarInfo 8040 +1000
TarInfo 9040 +1000
TarInfo 10040 +1000
TarInfo 11040 +1000
TarInfo 12040 +1000
这种情况一直持续到处理完所有 30,000 个文件。
只是为了确保,我已经注释掉了创建流和处理它的行。内存使用量保持不变 - TarInfo 实例被泄露。
我使用的是 Python 3.4.1,这种行为在 Ubuntu、OS X 和 Windows 上是一致的。