• 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__方法,否则,就需要自己去手动释放带有循环引用的资源。前者更好的选择。

  • 相关阅读:
    【转】二叉树中两个节点的最近的公共父节点
    查找最小的k个元素
    字符串的排列
    php字符串操作
    Android手机app启动的时候第一个Activity必须是MainActivity吗
    ASP.NET网站前端页面的复制
    MySQL字段类型说明
    转:Zend Server Community Edition(CE) 安装手记
    数据库远程导入导出步骤
    转:两种转换mysql数据编码的方法latin1转utf8
  • 原文地址:https://www.cnblogs.com/ankier/p/2987762.html
Copyright © 2020-2023  润新知