【问题标题】:does return object from function lead to memory leak从函数返回对象是否会导致内存泄漏
【发布时间】:2016-02-01 08:21:52
【问题描述】:

以下面的代码为例,函数返回对象是否会导致内存泄漏?

我很好奇对象handle 在被函数use_age 使用后会发生什么。

class Demo(object):

    def _get_mysql_handle(self):
        handle = MySQLdb.connect(host=self.conf["host"],
                             port=self.conf["port"],
                             user=self.conf["user"],
                             passwd=self.conf["passwd"],
                             db=self.conf["db"])
        return handle

    def use_age(self):
        cursor = self._get_mysql_handle().cursor()

if __name__ == "__main__":
      demo = Demo()
      demo.use_age()

【问题讨论】:

  • 不,你为什么会这样想?
  • 想到C/C++,好奇python的规则是什么。

标签: python python-2.7 memory-leaks


【解决方案1】:

不,该代码不会导致内存泄漏。

CPython 通过引用计数来处理对象的生命周期。在您的示例中,引用计数回落到 0,并且再次删除数据库连接对象。

  • _get_mysql_handle中的本地名称handle是一个引用,当_get_mysql_handle返回时被删除。
  • 保存来自self._get_mysql_handle() 的返回值的堆栈是另一个堆栈,当表达式结果完成时它也会被丢弃。
  • .cursor() 是一个方法,因此在该方法退出之前,它将有另一个引用该方法的 self 参数。
  • .cursor() 的返回值可能存储了一个引用,当游标本身被收割时它会被删除。这取决于use_age() 方法中本地cursor 变量的生命周期。作为本地人,它不会超出use_age() 功能。

其他 Python 实现使用垃圾回收策略;例如,Jython 使用 Java 运行时工具。该对象的寿命可能会更长,但不会“泄漏”。

在 Python 版本 __del__ 方法的自定义类创建循环引用。这些是gc module 不会中断的循环引用。您可以在gc.garbage object 中内省此类链。

【讨论】:

  • 那我需要在连接上调用close还是留给对象析构函数?
  • @luoluo:对象析构函数会处理它,但如果您依赖事务,您可能希望更直接地控制连接何时关闭,尤其是在您使用 Jython 或 IronPython 时。跨度>
  • 以上面的代码为例,_get_mysql_handle返回的连接只使用一次,之后该对象就应该没有引用了。简而言之,在这种情况下,似乎有一个隐式关闭。这是真的吗?
  • @luoluo:MySQL连接对象在对象被删除时会隐式关闭,是的。 Python 确保它被删除。
猜你喜欢
  • 1970-01-01
  • 2023-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-05
  • 1970-01-01
  • 2011-02-01
相关资源
最近更新 更多