使用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 ...
随机推荐
- Linux shell 脚本攻略之比较与测试
摘自:<Linux shell 脚本攻略>Page30-33
- 对于android触摸事件模型的一些理解
body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...
- CentOS-6.5安装配置Tomcat7
一.下载tomcat cd /usr/local/src wget http://mirror.bit.edu.cn/apache/tomcat/tomcat-7/v7.0.50/bin/apache ...
- linux上传下载
linux传下载 1.可以通过xftp连接服务器直接 拖拽 2.yum install lrzsz 通过rz/sz命令上传下载
- CF A and B and Compilation Errors (排序)
A and B and Compilation Errors time limit per test 2 seconds memory limit per test 256 megabytes inp ...
- MySQL数据库的存储结构
--把若干条sql语句封装起来,起个名字,叫做过程,也是没有返回值的函数 --把这个过程存储在数据库中->存储过程 --存储过程的创建过程 create procedure proceduceN ...
- Git CMD - diff: Show changes between commits, commit and working tree, etc
命令格式 git diff [options] [<commit>] [--] [<path>…] git diff [options] --cached [<comm ...
- 初学Android: 四大组件之Activity
1.activity (1)一个Activity通常就是一个单独的屏幕(窗口),简单来说activity就是一个交互界面,一般应用程序都要由一个或者多个activity组成. (2)Activity之 ...
- 使用TreeView+ListBox+TxtBox 资料管理器
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- js中小数的操作及数字类型的验证
1.丢弃小数部分,保留整数部分js:parseInt(7/2) 2.向上取整,有小数就整数部分加1js: Math.ceil(7/2) 3,四舍五入. js: Math.round(7/2) 4,向下 ...