python3 urllib 内存泄露_使用urllib2的HttpResponse导致内存不回收(内存泄漏)

问题出现环境:python 2.7.1(X)及以下, Windows(或CentOS)

这个问题产生在lib/urllib2.py的line 1174 (python 2.7.1),导致形成了cycle,即使调用gc.collect()也不能释放到HttpResponse等相关联对象(gc.garbage可以查看)

1r.recv = r.read2

3 fp = socket._fileobject(r, close=True)4

5 resp =addinfourl(fp, r.msg, req.get_full_url())6

7 resp.code =r.status8

9 resp.msg =r.reason10

11 return resp

在python官方网站上很早发现了此BUG(见以下两个issues),但就是没有正式解决此问题。不过以下两个threads可以得到workarounds。

引申一下,如果python代码写成这样(自己写代码犯的一个错误),会导致以上相同cycle问题,从而导致内存泄漏。

1 classT(object):2 def __init__(self):3 self.test = self.test04

5 def test0(self, d={}):6 d['a'] = 1

在python shell运行如下:

1 Python 2.7.1 (r271:86832, Nov 27 2010, 18:30:46) [MSC v.1500 32bit (Intel)] on win322 Type "help", "copyright", "credits" or "license" formore information.3 >>> importgc4 >>>gc.set_debug(gc.DEBUG_LEAK)5 >>> classT(object):6 ... def __init__(self):7 ... self.test = self.test08 ...9 ... def test0(self, d={}):10 ... d['a'] = 1

11 ...12 >>> t=T()13 >>> delt14 >>>gc.collect()15 gc: collectable

16 gc: collectable

17 gc: collectable

18 3

19 >>> for _item ingc.garbage:20 ... print_item21 ...22 <__main__.t object at>

23 >

24 {'test': >}

导致不能释放内存即是以上红色字体部分,可以通过调用GC自带两方法查看为什么会形成cycle。

1 >>> t2=T()2 >>>gc.get_referrers(t2)3 [>, {'__builtins__': , 't2': <__main__.t object at>, '__package__': None, 'gc'

4 : , 'T': , '__name__': '__main__', '__doc__': None, '_item': {'test': >}}]5 >>> for _item ingc.get_referrers(t2):6 ... print_item7 ...8>

9 {'__builtins__': , 't2': <__main__.t object at>, '__package__': None, 'gc': , 'T': , '__name

10 __':'__main__','__doc__': None,'_item': {...}}

11 >>> for _item ingc.get_referents(t2):12 ... print_item13 ...14{'test': >}15

gc.get_referrers:Return the list of objects that directly refer to any of objs.

返回引用t2的对象,包括>对象

gc.get_referents:Return a list of objects directly referred to by any of the arguments.

返回被t2引用的对象,包括>对象

以下情况不产生cycle:

1 classT2(object):2 def __init__(self):3 pass

4

5 deftest(self):6 returnself.test0()7

8 def test0(self, d={}):9 d['a'] = 1

10 classT3(object):11 def __init__(self):12 self.test =self.test013

14 @classmethod15 def test0(cls, d={}):16 d['a'] = 1

17 kkk = test0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值