使用urllib2的HttpResponse导致内存不回收(内存泄漏)
- 问题出现环境: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导致内存不回收(内存泄漏)的更多相关文章
- linux查看内存和回收内存
清理前内存使用情况 free -m free -g echo 1 > /proc/sys/vm/drop_caches 清理后内存使用情况 free -m
- davlik虚拟机内存管理之一——内存分配
转载自http://www.miui.com/thread-74715-1-1.html dalvik虚拟机是Google在Android平台上的Java虚拟机的实现,内存管理是dalvik虚拟机中的 ...
- 记一次内存无法回收导致频繁fullgc机器假死的思路
确定挂机 络绎不绝的来不同类型的bug 当bug滚滚而来时,不要怀疑,你的发布的应用基本是不可用状态了.观察哨兵监控数据,特别是内存打到80%基本就挂机了,或者监控数据缺失也基本是挂机了.此时应当马上 ...
- Andorid 内存溢出与内存泄露,几种常见导致内存泄露的写法
内存泄露,大部分是因为程序的逻辑不严谨,但是又可以跑通顺,然后导致的,内存溢出不会报错,如果不看日志信息是并不知道有泄露的.但是如果一直泄露,然后最终导致的内存溢出,仍然会使程序挂掉.内存溢出大部分是 ...
- JVM是如何分配和回收内存?有实例!
上一篇博客我简单介绍了下如何手动计算一个Java对象到底占用多少内存?今天就想聊下这个内存JVM到底是是如何分配和回收的. Java整体来说还是一个GC比较友好的语言,无论是分代的垃圾收集,还是基于G ...
- 【转载】Java垃圾回收内存清理相关(虚拟机书第三章),GC日志的理解,CPU时间、墙钟时间的介绍
主要看<深入理解Java虚拟机> 第三张 P84 开始是垃圾收集相关. 1. 1960年诞生于MIT的Lisp是第一门采用垃圾回收的语言. 2. 程序计数器.虚拟机栈.本地方法栈3个区域随 ...
- java 内存 垃圾回收调优
要了解Java垃圾收集机制,先理解JVM内存模式是非常重要的.今天我们将会了解JVM内存的各个部分.如何监控以及垃圾收集调优. Java(JVM)内存模型 正如你从上面的图片看到的,JVM内存被分成多 ...
- 重读《深入理解Java虚拟机》二、Java如何分配和回收内存?Java垃圾收集器如何工作?
线程私有的内存区域随用户线程的结束而回收,内存分配编译期已确定,内存分配和回收具有确定性.共享线程随虚拟机的启动.结束而建立和销毁,在运行期进行动态分配.垃圾收集器主要对共享内存区域(堆和方法区)进行 ...
- 疑难杂症--SQL SERVER 2012下数据库内存异常回收
--=================================================================== --背景: 在一台SQL SERVER 2012 SP1(1 ...
随机推荐
- cocos2d-x触摸分发器原理
屏幕捕捉到触摸消息的派发流程: 如果有一个组件如果想要接收触摸事件,会通过继承一个CCTouchDelegate接口注册给CCTouchDispatcher,CCTouchDispatcher 中维护 ...
- CSS设置行内元素和块级元素的水平居中、垂直居中
CSS设置行内元素的水平居中 div{text-align:center} /*DIV内的行内元素均会水平居中*/ CSS设置行内元素的垂直居中 div{height:30px; line-heigh ...
- Lamp下安装memcached
1.先安装 libevent,再安装 Memcached主程序 # tar xf libevent-2.0.21-stable.tar.gz # cd libevent-2.0.21-stable # ...
- 关于Java序列化和Hadoop的序列化
import java.io.DataInput; import java.io.DataOutput; import java.io.DataOutputStream; import java.io ...
- hostname
http://www.linuxidc.com/Linux/2014-11/109238.htm
- button倒计时可点击
- 学习css简单内容
Css的class,ID和上下文选择符 Class选择符. Class选择符用来配置某一类css规则,将其应用到网页中一个或多个区域.配置一类样式时,要将选择符配置成类名.在类名前加(.).类名必须以 ...
- Redis 命令 - Lists
BLPOP key [key ...] timeout Remove and get the first element in a list, or block until one is availa ...
- 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 ...
- VHD轻松实现双系统
VHD 是微软虚拟磁盘文件. VHD(Microsoft Virtual Hard Disk format). 目前可以使用Microsoft Virtual PC 2007 and Micros ...