2016-02-01 94 views
-1

以下面的代碼爲例,是否從函數返回對象導致內存泄漏?確實從函數返回對象導致內存泄漏

我對函數use_age使用後的對象handle發生了什麼感到非常好奇。

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() 
+0

不,你爲什麼這麼想? –

+0

想到'C/C++',好奇python的規則是什麼。 – luoluo

回答

4

不,該代碼不會導致內存泄漏。

CPython通過引用計數來處理對象的生命週期。在你的例子中,引用計數回落到0,並且數據庫連接對象再次被刪除。

  • 本地名稱handle_get_mysql_handle是一個參考,它是當_get_mysql_handle回報率下降。
  • 保存從self._get_mysql_handle()返回值的堆棧是另一個,當表達式結果完成時它也被刪除。
  • .cursor()是一種方法,因此它會爲該方法的self參數提供另一個參考,直到該方法退出。
  • .cursor()的返回值可能會存儲一個引用,它會在獲得遊標本身時被刪除。那麼這取決於use_age()方法中當地cursor變量的使用期限。作爲本地,它不會超越use_age()功能。

其他Python實現使用垃圾收集策略;例如,Jython使用Java運行時設施。物體可能活得更久一些,但不會「泄漏」。

在Python版本< 3.4中,您需要注意使用自定義類創建循環引用,這些自定義類定義了__del__方法。這些是gc module不會中斷的循環引用。你可以在gc.garbage object中反思這樣的鏈。

+0

那麼我需要在連接上調用close還是將它留給對象析構函數? – luoluo

+0

@luoluo:對象析構函數會照顧它,但是如果你依賴事務,你可能想要控制何時更直接關閉連接,特別是如果你使用Jython或IronPython。 –

+0

以上面的代碼爲例,'_get_mysql_handle'返回的連接只使用一次,之後應該沒有該對象的引用。總之,在這種情況下,似乎有一個隱式關閉。這是真的? – luoluo