python不会为元组释放内存,不是吗?

时间:2011-11-11 19:41:14

标签: python google-app-engine memory-leaks tuples backend

根据我读到的这篇文章,看起来不可变的类型可能会变成不朽的。

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

我目前正致力于解决在Google应用引擎上运行的网络服务的内存使用问题。 “使用太多元组”是否可能是导致此问题的潜在原因?


感谢您的回复: 我在谷歌应用引擎后端实例上运行我的代码,它有一个内存使用上限(128mb)。它说我使用的内存比允许的多,并且停止了我的实例。正如评论所提到的,它可能是“内存使用量仍然很大”而不是“内存泄漏”。

3 个答案:

答案 0 :(得分: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,内存使用情况)的信息,你可以尝试这样做 - 可能连续几次,这应该会给你一些更高的内存使用量。

答案 1 :(得分:1)

我没有在你链接的文章中看到,元组是Python维护自己的免费列表的类型之一。它们很可能是,但根据this article,具体的罪魁祸首是intfloat s,dictlist。虽然那篇文章是从2005年开始的,但从那以后情况可能发生了变化......

在Python 2.6或更高版本中,除intfloat以外的所有内容的免费列表都可以使用gc.collect(2)清除,我想这对您没有帮助GAE,但我想我会提到它。

答案 2 :(得分: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可能无法释放它们