python垃圾回收与内存泄露

本文探讨了Python的垃圾回收机制,当对象引用计数为零时,内存会被自动释放。垃圾回收过于频繁可能影响程序性能。通过调优,避免无效的垃圾回收,能显著提升程序执行效率。同时,提到了Python的内存泄露问题,特别是引用循环可能导致内存泄露。通过设置gc.debug和调用gc.collect,可以帮助定位内存泄露的位置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Python垃圾回收

Python垃圾回收的工作原理是:为每个内存对象维护一个引用计数,当对象的引用计数为零时解释器会自动释放内存。

在Python中,有2中方式可以触发垃圾回收:一种方式是用户显示调用gc.collect(),另一种方式是每次Python为新对象分配内存时,检查threshold阀值,当对象数量超过threshold设置的阀值就开始进行垃圾回收。但是Python垃圾回收频频触发会影响程序执行的性能

优化前:频繁做无用垃圾回收

[root@xiaoxiong gc]# cat 2.py 
data = range(1,4000000)   
wdict = dict(zip(data,data))  
[root@xiaoxiong gc]# time python 2.py
real    0m17.551s
user    0m17.123s
sys     0m0.420s
[root@xiaoxiong gc]# 


优化后的垃圾回收程序


[root@xiaoxiong gc]# cat 1.py 
import gc   
gc.disable()   
data = range(1,5000000)   
wdict = dict(zip(data,data))   
gc.enable()  
[root@xiaoxiong gc]# 
[root@xiaoxiong gc]# 
[root@xiaoxiong gc]# time python 1.py
real    0m2.596s
user    0m2.068s
sys     0m0.513s
[root@xiaoxiong gc]# 


优化前的程序无法释放部分内存,而垃圾回收程序却在做无用功,程序的执行性能将大打折扣。调优后在程序片段运行的这段时间内禁止进行垃圾回收,程序性能大为提高。

Python内存泄露

Python虽然能自动垃圾回收,但是如果使用不当,也会造成内存泄露,造成这种现象的原因一般都是由于某些对象引用了自身,造成了类似的一个引用循环。

下面的程序提供了更多的信息来帮助定位泄露发生地点的办法。

[root@xiaoxiong cb8]# 
[root@xiaoxiong cb8]# cat 1.py 
import gc, time
def dump_garbage():
    """ show us what the garbage is about """
    # Force collection
    print "\nGARBAGE:"
    gc.collect()
    print "\nGARBAGE OBJECTS:"
    for x in gc.garbage:
        print 'hello'
        s = str(x)
        #if len(s) > 80: s = s[:77]+'...'
        print type(x),"\n  ", s
        
class Obj:  
    def __init__(self,name='A'):  
        self.name = name  
        print '%s inited' % self.name  
    def __del__(self):  
        print '%s deleted' % self.name  
        
def hello():
    dump_garbage()
        
if __name__=="__main__":
    gc.enable()
    gc.set_debug(gc.DEBUG_LEAK)
    # Simulate a leak (a list referring to itself) and show it
    
    a = Obj('A')  
    b = Obj('B')  
    c = Obj('c')  
  
    c.attrObj = b  
    b.attrObj = c     
    
    del a
    del b
    del c
    
[root@xiaoxiong cb8]# python 1.py 
A inited
B inited
c inited
A deleted
GARBAGE:
gc: uncollectable <Obj instance at 0x7f59410c9ea8>
gc: uncollectable <Obj instance at 0x7f59410c9dd0>
gc: uncollectable <dict 0x129f310>
gc: uncollectable <dict 0x12af7f0>
GARBAGE OBJECTS:
hello
<type 'instance'> 
   <__main__.Obj instance at 0x7f59410c9ea8>
hello
<type 'instance'> 
   <__main__.Obj instance at 0x7f59410c9dd0>
hello
<type 'dict'> 
   {'name': 'B', 'attrObj': <__main__.Obj instance at 0x7f59410c9dd0>}
hello
<type 'dict'> 
   {'name': 'c', 'attrObj': <__main__.Obj instance at 0x7f59410c9ea8>}
[root@xiaoxiong cb8]# 

该程序第一步调用gc.set_debug,通知gc模块将泄露的对象放入gc.garbage列表中,而不是将它们回收利用。然后dump_garbage函数调用gc.collect来强制回收进程的运行,即使当前内存还很充裕,这样它就可以检查gc.garbage中的每一项并打印出类型和内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值