Python垃圾回收机制:gc模块(zz)
在Python中,为了解决内存泄露问题,采用了对象引用计数,并基于引用计数实现自动垃圾回收。
由于Python 有了自动垃圾回收功能,就造成了不少初学者误认为不必再受内存泄漏的骚扰了。但如果仔细查看一下Python文档对 __del__() 函数的描述,就知道这种好日子里也是有阴云的。下面摘抄一点文档内容如下:
Some common situations that may prevent the reference count of an object from going to zero include: circular references between objects (e.g., a doubly-linked list or a tree data structure with parent and child pointers); a reference to the object on the stack frame of a function that caught an exception (the traceback stored in sys.exc_traceback keeps the stack frame alive); or a reference to the object on the stack frame that raised an unhandled exception in interactive mode (the traceback stored in sys.last_traceback keeps the stack frame alive). |
可见,有 __del__() 函数的对象间的循环引用是导致内存泄漏的主凶。但没有__del__()函数的对象间的循环引用是可以被垃圾回收器回收掉的。
如何知道一个对象是否内存泄露掉了呢?
可以通过Python的扩展模块gc来查看不能回收掉的对象的详细信息。
例
例1:没有出现内存泄露的
import gc
import sys class CGcLeak(object):
def __init__(self):
self._text='#'*10 def __del__(self):
pass def make_circle_ref():
_gcleak=CGcLeak() print("_gcleak ref count0:{}".format(sys.getrefcount(_gcleak)))
del _gcleak try:
print("_gcleak ref count:{}".format(sys.getrefcount(_gcleak)))
except UnboundLocalError:
print("_gcleak is invalid!") def test_gcleak():
gc.enable() print("begin leak test...")
make_circle_ref() print
"\nbegin collect..."
_unreachable = gc.collect()
print("unreachable object num:{}".format(_unreachable))
print("garbage object num:{}".format(len(gc.garbage))) if __name__ == "__main__":
test_gcleak()
结果
C:\Python35\python.exe C:/wcf/django/ftest/ftest.py
begin leak test...
_gcleak ref count0:2
_gcleak is invalid!
unreachable object num:0
garbage object num:0 Process finished with exit code 0
例2:对自己的循环引用造成内存泄露
import gc
import sys class CGcLeak(object):
def __init__(self):
self._text='#'*10 def __del__(self):
pass def make_circle_ref():
_gcleak=CGcLeak()
_gcleak._self = _gcleak
print("_gcleak ref count0:{}".format(sys.getrefcount(_gcleak)))
del _gcleak try:
print("_gcleak ref count:{}".format(sys.getrefcount(_gcleak)))
except UnboundLocalError:
print("_gcleak is invalid!") def test_gcleak():
gc.enable() print("begin leak test...")
make_circle_ref() print
"\nbegin collect..."
_unreachable = gc.collect()
print("unreachable object num:{}".format(_unreachable))
print("garbage object num:{}".format(len(gc.garbage))) if __name__ == "__main__":
test_gcleak()
结果是:
C:\Python35\python.exe C:/wcf/django/ftest/ftest.py
begin leak test...
_gcleak ref count0:3
_gcleak is invalid!
unreachable object num:2
garbage object num:0 Process finished with exit code 0
例3:多个对象间的循环引用造成内存泄露
import gc
import sys class CGcLeakA(object):
def __init__(self):
self._text='#'*10 def __del__(self):
pass class CGcLeakB(object):
def __init__(self):
self._text='$'*10 def __del__(self):
pass def make_circle_ref():
_a=CGcLeakA()
_b = CGcLeakB()
_a.s=_b
_b.s=_a print("ref count0:_a is {},_b is {}".format(sys.getrefcount(_a),sys.getrefcount(_a)))
del _a
del _b try:
print("ref count:_a is {}".format(sys.getrefcount(_a)))
except UnboundLocalError:
print("_a is invalid!") def test_gcleak():
gc.enable() print("begin leak test...")
make_circle_ref() print
"\nbegin collect..."
_unreachable = gc.collect()
print("unreachable object num:{}".format(_unreachable))
print("garbage object num:{}".format(len(gc.garbage))) if __name__ == "__main__":
test_gcleak()
运行结果:
import gc
import sys class CGcLeakA(object):
def __init__(self):
self._text='#'*10 def __del__(self):
pass class CGcLeakB(object):
def __init__(self):
self._text='$'*10 def __del__(self):
pass def make_circle_ref():
_a=CGcLeakA()
_b = CGcLeakB()
_a.s=_b
_b.s=_a print("ref count0:_a is {},_b is {}".format(sys.getrefcount(_a),sys.getrefcount(_a)))
del _a
del _b try:
print("ref count:_a is {}".format(sys.getrefcount(_a)))
except UnboundLocalError:
print("_a is invalid!") def test_gcleak():
gc.enable() print("begin leak test...")
make_circle_ref() print
"\nbegin collect..."
_unreachable = gc.collect()
print("unreachable object num:{}".format(_unreachable))
print("garbage object num:{}".format(len(gc.garbage))) if __name__ == "__main__":
test_gcleak()
转自:
http://www.cnblogs.com/kaituorensheng/p/4449457.html
Python垃圾回收机制:gc模块(zz)的更多相关文章
- Python垃圾回收机制:gc模块
在Python中,为了解决内存泄露问题,采用了对象引用计数,并基于引用计数实现自动垃圾回收. 由于Python 有了自动垃圾回收功能,就造成了不少初学者误认为不必再受内存泄漏的骚扰了.但如果仔细查看一 ...
- 浅析Python垃圾回收机制!
Python垃圾回收机制 目录 Python垃圾回收机制 1. 内存泄露 2. Python什么时候启动垃圾回收机制? 2.1 计数引用 2.2 循环引用 问题:引用计数是0是启动垃圾回收的充要条件吗 ...
- 简述Python垃圾回收机制和常量池的验证
目录 通过代码验证python解释器内部使用了常量池 Python的引入 变量的引入 为什么要有变量 定义变量 常量引入 常量池引入 Python解释器 Python变量存储机制 Python垃圾回收 ...
- 垃圾回收机制GC
垃圾回收机制GC 我们已经知道,name = 'leethon'这一赋值变量的操作,是将变量与数据值相绑定. 而数据值是存储到内存中的,有时变量会重新赋值即绑定其他数据值,而使得原本的数据值无法通过变 ...
- 垃圾回收机制GC知识再总结兼谈如何用好GC
一.为什么需要GC 应用程序对资源操作,通常简单分为以下几个步骤: 1.为对应的资源分配内存 2.初始化内存 3.使用资源 4.清理资源 5.释放内存 应用程序对资源(内存使用)管理的方式,常见的一般 ...
- 垃圾回收机制GC知识再总结兼谈如何用好GC(转)
作者:Jeff Wong 出处:http://jeffwongishandsome.cnblogs.com/ 本文版权归作者和博客园共有,欢迎围观转载.转载时请您务必在文章明显位置给出原文链接,谢谢您 ...
- python垃圾回收机制与小整数池
python垃圾回收机制 当引用计数为0时,python会删除这个值. 引用计数 x = 10 y = x del x print(y) 10 引用计数+1,引用计数+1,引用计数-1,此时引用计数为 ...
- python垃圾回收机制:引用计数 VS js垃圾回收机制:标记清除
js垃圾回收机制:标记清除 Js具有自动垃圾回收机制.垃圾收集器会按照固定的时间间隔周期性的执行. JS中最常见的垃圾回收方式是标记清除. 工作原理 当变量进入环境时,将这个变量标记为"进入 ...
- 垃圾回收机制GC知识再总结兼谈如何用好GC(其他信息: 内存不足)
来源 图像操作,易内存泄露,边界像素 一.为什么需要GC 应用程序对资源操作,通常简单分为以下几个步骤: 1.为对应的资源分配内存 2.初始化内存 3.使用资源 4.清理资源 5.释放内存 应用程序对 ...
随机推荐
- ORACLE和SQL语法区别归纳
数据类型比较类型名称 Oracle SQLServer 比较字符数据类型 CHAR CHAR 都是固定长度字符资料但oracle里面最大度为2kb,SQLServer里面最大长度为8kb ...
- Android隐藏键盘
今天接到的任务是在验证码输入框中加入键盘监听事件,需要点击Enter实现登录,这个比较好实现,但是在登录时,键盘并没有隐藏掉,看上去很别扭,因此,百度了一堆方法,但是都无济于事,最后找到了一个,如下, ...
- 在delphi中如何解决空格的问题。。。。烦死 了。。。。
我每次从数据库里面取数据出来和Edit里面的进行比较的时候总是会受到空格的困扰...老是干扰我...如果我用trim 所有都做去掉所有的空格那么这样就非常麻烦又繁琐..有没有什么方法可以忽略空格的.. ...
- BZOJ4311 向量(线段树分治+三分)
由点积的几何意义(即投影)可以发现答案一定在凸壳上,并且投影的变化是一个单峰函数,可以三分.现在需要处理的只有删除操作,线段树分治即可. #include<iostream> #inclu ...
- Netscaler的超高端口复用助力应对公网地址紧张
Netscaler的超高端口复用助力应对公网地址紧张 http://blog.51cto.com/caojin/1898351 经常会有人问一个IP只有65535(姑且不考虑预留端口),从Big-ip ...
- [洛谷P4124][CQOI2016]手机号码
题目大意:给你两个$l,r$,求出$[l,r]$中符合要求的数,要求为至少有$3$个相邻的相同数字,且不可以同时出现$8$和$4$ 题解:数位$DP$ 卡点:无 C++ Code: #include ...
- JS容易理解错误的地方
在这端代码执行的末尾,你会不会hi变量回事函数中的hi了?你会不会认为这不是按引用传递了? 对值传递和引用传递产生质疑了? 1 var hi = {}; 2 function sayHello(hi) ...
- BZOJ1103 [POI2007]大都市meg 【树剖】
1103: [POI2007]大都市meg Time Limit: 10 Sec Memory Limit: 162 MB Submit: 3038 Solved: 1593 [Submit][S ...
- 在iis上部署ssl证书 https
1.取走证书下载下来的文件.解压iis的压缩包. 2.打开internet信息服务iis管理器 3.双击打开后,选择导入,导入我们刚刚解压得到的pfx文件,这个pfx文件就是你需要部署域名的那个文件. ...
- [学习笔记]LCT进阶操作
LCT总结——应用篇(附题单)(LCT) 一般都是维护链的操作.split即可搞定. 进阶操作的话,处理好辅助树和原树的关系即可搞定. 其实,最大的区别就是,splay随便转,辅助树形态变了,但是原树 ...