2011-12-29 51 views
4

我有一个程序,加载和处理这种形式的大量的图片,:强行丢弃Python图像库的图像回收内存

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

当上有许多图像运行Python进程结束使用大量的内存 - 远远超过任何一个图像应该考虑的。不用说,这最终会导致页面文件抖动。

我认为(虽然我不是100%确定,显然),这是因为之前的图像占用内存直到它们被垃圾收集。

有没有办法强行丢弃它们?我无法在PIL reference中找到一个。我想到了使用del im,但我明白这只是简单地从本地范围中删除名称'im',并且有效地将其重新分配到循环的顶部。

+1

附注:您可能希望检查['weakref'模块](http://docs.python.org/library/weakref.html)。它不是直接回答你的问题,但使用它可能会让你绕过某些不可避免的代码行为。 – mac 2011-12-29 08:53:58

回答

3

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

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

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

+0

在Python中没有任何东西可以被销毁;但它不一定适用于诸如PIL等外部模块。 ;-)打印每种类型的计数的想法听起来很好,所以我首先尝试。 – Edmund 2011-12-29 08:11:07

+0

@Edmund,真的,外部模块可以提供他们喜欢的任何API。我不知道任何支持释放对象的支持。 (其他资源如套接字/文件/等是的,但内存,不。) – 2011-12-29 08:21:30