Python不会释放元组的内存,是吗?
根据我读的一篇文章,似乎不可变类型可能会变得“永生”。
http://effbot.org/pyfaq/why-doesnt-python-release-the-memory-when-i-delete-a-large-object.htm
我现在正在解决一个内存使用问题,这个问题出现在我在谷歌应用引擎上运行的网络服务中。请问“使用太多元组”会不会是导致这个问题的一个潜在原因呢?
谢谢你的回复:我在谷歌应用引擎的后台实例上运行我的代码,它有一个内存使用上限(128MB)。系统提示我使用的内存超过了允许的范围,因此停止了我的实例。正如评论中提到的,这可能是“内存使用仍然很大”,而不是“内存泄漏”。
3 个回答
不可变类型并不是说它永远存在。它所占用的内存仍然归Python管理,但这部分内存可以被其他对象使用。
循环依赖可能会导致内存泄漏:
class Parent(object):
def __init__(self):
self.offspring = Child(self)
def __del__(self):
# doesn't matter what goes here, gc will not be able to auto collect
# freed Parents and Childs
class Child(object):
def __init__(self, parent):
self.parent = parent
John_Doe = Parent()
在这种情况下,你有一个Child
(子对象)链接着它的Parent
(父对象),而这个Parent
又链接着它的Child
。这样一来,Python可能会在释放这些对象时遇到困难。
我在你链接的文章里没看到元组(tuples)是Python自己管理的空闲列表之一。它们可能是,但根据这篇文章,具体的罪魁祸首是int
(整数)、float
(浮点数)、dict
(字典)和list
(列表)。虽然这篇文章是2005年的,可能之后有变化……
在Python 2.6或更高版本中,除了int
和float
以外的所有类型的空闲列表都可以通过gc.collect(2)
来清理,我想这对你在GAE上可能没什么帮助,但我还是提一下。
这篇文章没有具体说明不可变类型,而是提到:
另一个可能导致内存使用过多的原因是,Python 对某些对象类型(包括整数和浮点数)使用了所谓的“空闲列表”。
我不知道你能在 GAE 进程中获取到什么信息,但你可以在自己的系统上尝试这个实验。
首先,启动一个 Python 解释器并找到进程。然后运行这个命令:
>>> many_tuples = [() for x in range(5000000)] #replace with xrange for 2.x
接着,看看内存使用情况。你刚刚创建了一个包含 500 万个元组的列表。现在输入:
>>> del many_tuples
在我的系统上(Python 3.2,Win 7),我的内存使用量一下子增加了大约 20k,然后在我 del
这个变量后又减少了同样的量。如果你能获取到关于你进程的信息(CPU、内存使用情况),你可以尝试这样做——也许连续几次,这样可以让你看到几次内存使用量的峰值。