Python不会释放元组的内存,是吗?

2 投票
3 回答
1645 浏览
提问于 2025-04-17 06:08

根据我读的一篇文章,似乎不可变类型可能会变得“永生”。

http://effbot.org/pyfaq/why-doesnt-python-release-the-memory-when-i-delete-a-large-object.htm

我现在正在解决一个内存使用问题,这个问题出现在我在谷歌应用引擎上运行的网络服务中。请问“使用太多元组”会不会是导致这个问题的一个潜在原因呢?


谢谢你的回复:我在谷歌应用引擎的后台实例上运行我的代码,它有一个内存使用上限(128MB)。系统提示我使用的内存超过了允许的范围,因此停止了我的实例。正如评论中提到的,这可能是“内存使用仍然很大”,而不是“内存泄漏”。

3 个回答

1

不可变类型并不是说它永远存在。它所占用的内存仍然归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可能会在释放这些对象时遇到困难。

1

我在你链接的文章里没看到元组(tuples)是Python自己管理的空闲列表之一。它们可能是,但根据这篇文章,具体的罪魁祸首是int(整数)、float(浮点数)、dict(字典)和list(列表)。虽然这篇文章是2005年的,可能之后有变化……

在Python 2.6或更高版本中,除了intfloat以外的所有类型的空闲列表都可以通过gc.collect(2)来清理,我想这对你在GAE上可能没什么帮助,但我还是提一下。

5

这篇文章没有具体说明不可变类型,而是提到:

另一个可能导致内存使用过多的原因是,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、内存使用情况),你可以尝试这样做——也许连续几次,这样可以让你看到几次内存使用量的峰值。

撰写回答