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

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

    r.recv = r.read

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

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

         resp.code = r.status

         resp.msg = r.reason

         return resp 

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

http://bugs.python.org/issue1208304

http://bugs.python.org/issue7464


  • 引申一下,如果python代码写成这样(自己写代码犯的一个错误),会导致以上相同cycle问题,从而导致内存泄漏。
 class T(object):
def __init__(self):
self.test = self.test0 def test0(self, d={}):
d['a'] = 1

在python shell运行如下:

 Python 2.7.1 (r271:86832, Nov 27 2010, 18:30:46) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import gc
>>> gc.set_debug(gc.DEBUG_LEAK)
>>> class T(object):
... def __init__(self):
... self.test = self.test0
...
... def test0(self, d={}):
... d['a'] = 1
...
>>> t=T()
>>> del t
>>> gc.collect()
gc: collectable <T 0260D870>
gc: collectable <instancemethod 01DCFDF0>
gc: collectable <dict 0260EA50>
3
>>> for _item in gc.garbage:
... print _item
...
<__main__.T object at 0x0260D870>
<bound method T.test0 of <__main__.T object at 0x0260D870>>
{'test': <bound method T.test0 of <__main__.T object at 0x0260D870>>}

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

 >>> t2=T()
>>> gc.get_referrers(t2)
[<bound method T.test0 of <__main__.T object at 0x0260D890>>, {'__builtins__': <module '__builtin__' (built-in)>, 't2': <__main__.T object at 0x0260D890>, '__package__': None, 'gc'
: <module 'gc' (built-in)>, 'T': <class '__main__.T'>, '__name__': '__main__', '__doc__': None, '_item': {'test': <bound method T.test0 of <__main__.T object at 0x0260D870>>}}]
>>> for _item in gc.get_referrers(t2):
... print _item
...
<bound method T.test0 of <__main__.T object at 0x0260D890>>
{'__builtins__': <module '__builtin__' (built-in)>, 't2': <__main__.T object at 0x0260D890>, '__package__': None, 'gc': <module 'gc' (built-in)>, 'T': <class '__main__.T'>, '__name
__': '__main__', '__doc__': None, '_item': {...}}
>>> for _item in gc.get_referents(t2):
... print _item
...
{'test': <bound method T.test0 of <__main__.T object at 0x0260D890>>}
<class '__main__.T'>
gc.get_referrers:Return the list of objects that directly refer to any of objs.
返回引用t2的对象,包括<bound method T.test0 of <__main__.T object at 0x0260D890>>对象
gc.get_referents:Return a list of objects directly referred to by any of the arguments.
返回被t2引用的对象,包括<bound method T.test0 of <__main__.T object at 0x0260D890>>对象
  • 以下情况不产生cycle:
 class T2(object):
def __init__(self):
pass def test(self):
return self.test0() def test0(self, d={}):
d['a'] = 1
class T3(object):
def __init__(self):
self.test = self.test0 @classmethod
def test0(cls, d={}):
d['a'] = 1
kkk = test0
												

使用urllib2的HttpResponse导致内存不回收(内存泄漏)的更多相关文章

  1. linux查看内存和回收内存

    清理前内存使用情况 free -m free -g echo 1 > /proc/sys/vm/drop_caches 清理后内存使用情况 free -m

  2. davlik虚拟机内存管理之一——内存分配

    转载自http://www.miui.com/thread-74715-1-1.html dalvik虚拟机是Google在Android平台上的Java虚拟机的实现,内存管理是dalvik虚拟机中的 ...

  3. 记一次内存无法回收导致频繁fullgc机器假死的思路

    确定挂机 络绎不绝的来不同类型的bug 当bug滚滚而来时,不要怀疑,你的发布的应用基本是不可用状态了.观察哨兵监控数据,特别是内存打到80%基本就挂机了,或者监控数据缺失也基本是挂机了.此时应当马上 ...

  4. Andorid 内存溢出与内存泄露,几种常见导致内存泄露的写法

    内存泄露,大部分是因为程序的逻辑不严谨,但是又可以跑通顺,然后导致的,内存溢出不会报错,如果不看日志信息是并不知道有泄露的.但是如果一直泄露,然后最终导致的内存溢出,仍然会使程序挂掉.内存溢出大部分是 ...

  5. JVM是如何分配和回收内存?有实例!

    上一篇博客我简单介绍了下如何手动计算一个Java对象到底占用多少内存?今天就想聊下这个内存JVM到底是是如何分配和回收的. Java整体来说还是一个GC比较友好的语言,无论是分代的垃圾收集,还是基于G ...

  6. 【转载】Java垃圾回收内存清理相关(虚拟机书第三章),GC日志的理解,CPU时间、墙钟时间的介绍

    主要看<深入理解Java虚拟机> 第三张 P84 开始是垃圾收集相关. 1. 1960年诞生于MIT的Lisp是第一门采用垃圾回收的语言. 2. 程序计数器.虚拟机栈.本地方法栈3个区域随 ...

  7. java 内存 垃圾回收调优

    要了解Java垃圾收集机制,先理解JVM内存模式是非常重要的.今天我们将会了解JVM内存的各个部分.如何监控以及垃圾收集调优. Java(JVM)内存模型 正如你从上面的图片看到的,JVM内存被分成多 ...

  8. 重读《深入理解Java虚拟机》二、Java如何分配和回收内存?Java垃圾收集器如何工作?

    线程私有的内存区域随用户线程的结束而回收,内存分配编译期已确定,内存分配和回收具有确定性.共享线程随虚拟机的启动.结束而建立和销毁,在运行期进行动态分配.垃圾收集器主要对共享内存区域(堆和方法区)进行 ...

  9. 疑难杂症--SQL SERVER 2012下数据库内存异常回收

    --=================================================================== --背景: 在一台SQL SERVER 2012 SP1(1 ...

随机推荐

  1. cocos2d-x触摸分发器原理

    屏幕捕捉到触摸消息的派发流程: 如果有一个组件如果想要接收触摸事件,会通过继承一个CCTouchDelegate接口注册给CCTouchDispatcher,CCTouchDispatcher 中维护 ...

  2. CSS设置行内元素和块级元素的水平居中、垂直居中

    CSS设置行内元素的水平居中 div{text-align:center} /*DIV内的行内元素均会水平居中*/ CSS设置行内元素的垂直居中 div{height:30px; line-heigh ...

  3. Lamp下安装memcached

    1.先安装 libevent,再安装 Memcached主程序 # tar xf libevent-2.0.21-stable.tar.gz # cd libevent-2.0.21-stable # ...

  4. 关于Java序列化和Hadoop的序列化

    import java.io.DataInput; import java.io.DataOutput; import java.io.DataOutputStream; import java.io ...

  5. hostname

    http://www.linuxidc.com/Linux/2014-11/109238.htm

  6. button倒计时可点击

  7. 学习css简单内容

    Css的class,ID和上下文选择符 Class选择符. Class选择符用来配置某一类css规则,将其应用到网页中一个或多个区域.配置一类样式时,要将选择符配置成类名.在类名前加(.).类名必须以 ...

  8. Redis 命令 - Lists

    BLPOP key [key ...] timeout Remove and get the first element in a list, or block until one is availa ...

  9. Animated App Boot Example : Fastest animation at app boot time

    This iPhone app shows how to create an animation that is displayed when the app starts. The animatio ...

  10. VHD轻松实现双系统

    VHD 是微软虚拟磁盘文件.   VHD(Microsoft Virtual Hard Disk format). 目前可以使用Microsoft Virtual PC 2007 and Micros ...