强制丢弃Python Imaging Library(PIL)图像以释放内存

4

我有一个程序,它加载和处理很多这样的图像:

for fn in filenames:
    im = Image.open(fn)
    get_some_basic_stats(im)

当处理多张图片时,Python进程最终会使用大量内存——远远超过任何一张图片所占用的内存。很明显,这最终会导致页面文件被抛弃。
我猜测(尽管我不确定),这是因为以前的图像占用了内存,直到它们被垃圾收集。
有没有一种方法可以强制丢弃它们?在PIL参考文献中,我找不到这样的方法。我想使用del im,但我理解这只是从本地范围内删除名称“im”,实际上相当于在循环顶部重新分配它。

1
顺便提一下:您可能希望检查 weakref 模块。虽然它不直接回答您的问题,但使用它可能允许您绕过某些本来无法避免的代码行为。 - mac
1个回答

3

在Python中没有东西可以被明确地销毁。在CPython中,一切都是引用计数的,因此只要没有任何引用它,它就应该被释放。在您的情况下,这应该发生在下一个循环迭代中。您可以通过运行gc.collect()来强制循环垃圾回收器,但我怀疑这不会解决这里的问题。

您可以尝试:在循环结束时运行print sys.getrefcount(im)。它会告诉您有多少个对象引用了该图像。它应该为2(一个用于本地变量,一个用于作为getrefcount的参数的im)。如果它比这更大,那就解释了为什么对象没有被释放。

您还可以查看gc.getobjects(),它将返回Python系统中所有对象的列表。我会编写一个快速循环来计算不同类型的对象并打印它们。看看任何对象数量是否增加。


Python 中的确没有什么可以被销毁;但对于 PIL 等外部模块来说,这并不一定是真的。;-) 打印出每种类型的计数的想法听起来很棒,所以我先尝试了这个。 - Edmund
@Edmund,没错,外部模块可以提供任何他们想要的 API。但是我还不知道有哪个支持释放对象的。(像套接字/文件等其他资源是可以的,但内存不行。) - Winston Ewert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接