python类中显示重写__del__方法,引起循环引用的对象无法释放,造成垃圾泄露问题

通常情况下,python的gc 垃圾回收机制,有一套算法,可以用来回收循环引用的对象,避免内存泄露。

不过,有个例外的情况:显示重写了__del__方法。

例子:

#-*- coding: UTF-8 -*-
#-------------------------------------------------------------------------------
# Name:        
# Purpose:     
#
# Author:      ankier
#
# Created:     28-03-2013
# Copyright:   (c) ankier 2013
# Licence:     <your licence>
#-------------------------------------------------------------------------------
import gc
import time

class Teacher:
    def __init__(self):
        self.Stu = None
        
    def __del__(self):
        print '释放 Teacher实例'
        
class Student:
    def __init__(self):
        self.Tea = None
    
    def __del__(self):
        print '释放 Student实例'
    
def MethoTest():
    tea = Teacher()
    stu = Student()
    
    #设置循环引用
    tea.Stu = stu
    stu.Tea = tea  
    del tea
    del stu
        
if __name__ == '__main__':  
    gc.enable()
    gc.set_debug(gc.DEBUG_COLLECTABLE | gc.DEBUG_UNCOLLECTABLE | \
        gc.DEBUG_INSTANCES | gc.DEBUG_OBJECTS)
    
    MethoTest()
    
    print '开始内存回收...'
    _unreachable = gc.collect()
    print '无法到达的对象个数: %d' % _unreachable
    print '内存泄露的对象个数:%d' % len(gc.garbage)
    
    time.sleep(3)
    print '程序退出!'
    

输出结果:存在循环引用,所在再推出方法MethodTest 后,已经无法回收改2个对象,导致了内存泄露。

如果把重写__del__方法给注释掉,不主动重写,则即使存在循环引用,python gc 机制 也能很好的释放资源。

如下图结果,所有的资源已经释放掉了。因此,再python 代码编写过程中,建议不要重写__del__方法,否则,就需要自己去手动释放带有循环引用的资源。前者更好的选择。

 

 

posted on 2013-03-28 22:18  |残阳|露  阅读(1604)  评论(0编辑  收藏  举报

导航