Python垃圾回收之循环引用
来源:互联网 发布:知乎量子纠缠与超光速 编辑:程序博客网 时间:2024/05/15 18:32
什么情况存在内存泄露
- python引用计数 + 分代收集和标记清除(处理循环引用),进行垃圾回收,但如下两种情况依旧存在内存泄露:
- 第一是对象被另一个生命周期特别长(如全局变量)的对象所引用
- 第二是循环引用中的对象定义了
__del__
函数,简而言之,循环引用中Python无法判断析构对象的顺序,无法释放
相关术语
- reachable/collectable(unreachable/uncollectable)
- reachable是针对python对象而言,如果从根集(root)能到找到对象,那么这个对象就是reachable,与之相反就是unreachable,unreachable只存在于循环引用中的对象,Python的gc模块就是针对unreachable对象
- collectable是针对unreachable对象而言,如果这种对象能被回收,是collectable,如果不能被回收,即循环引用中的对象定义了
__del__
, 那么就是uncollectable。 即unreachable (循环引用)分成 collectable和ubcollectable(__del__
)
GC模块
This module provides access to the garbage collector for reference cycles.enable() -- Enable automatic garbage collection.disable() -- Disable automatic garbage collection.isenabled() -- Returns true if automatic collection is enabled.collect() -- Do a full collection right now. Tg
gc.set_debug(flags)
gc.DEBUG_COLLETABLE: 打印可以被垃圾回收器回收的对象
gc.DEBUG_UNCOLLETABLE: 打印无法被垃圾回收器回收的对象,即定义了__del__
的对象
gc.DEBUG_SAVEALL:所有的unreachable对象都将加入gc.garbage返回的列表
gc.garbage: 返回是unreachable对象,且不能被回收的的对象,如果设置SAVEALL,所有unreachable都加入此列表
A list of objects which the collector found to be unreachable but could not be freed (uncollectable objects). Starting with Python 3.4, this list should be empty most of the time, except when using instances of C extension types with a non-NULL tp_del slot.
禁用GC
只要能手动解决循环引用,就可以禁止GC模块来提高效率,因为GC适用于循环引用的垃圾回收机制。 如果可以确定代码没有循环引用,那么可以禁用GC模块
特殊说明(PEP442)
python3.4开始已经可以自动处理带有__del__
方法的循环引用,也不会发生内存泄露了
import gcclass Foo(object): def __init__(self): self.bar = None print('foo init') def __del__(self): print("foo del")class Bar(object): def __init__(self): self.foo = None print('bar init') def __del__(self): print('bar del')def collect_and_show_garbage(): print("Collecting...") n = gc.collect() print("unreachable objects:", n) print(gc.garbage)def func(): foo = Foo() bar = Bar() foo.bar = bar bar.foo = foo# gc.set_debug(gc.DEBUG_COLLECTABLE | gc.DEBUG_UNCOLLECTABLE)func()collect_and_show_garbage()
python2.7
foo init
bar init
Collecting…
(‘unreachable objects:’, 4)
[<main.Foo object at 0x101235550>, <main.Bar object at 0x1012355d0>]python3.6
foo init
bar init
Collecting…
foo del
bar del
unreachable objects: 4
[]
gc.collect() 返回unreachable的数目,所以无论2.7还是3.6都一样,但、3.6中可以处理循环引用且带有__del__
的情况,所以gc.garbage为空,当然如果没有__del__
方法,2.7中gc.garbage也是空
- Python垃圾回收之循环引用
- java垃圾回收之循环引用
- JAVA垃圾回收 之 引用计数 之 循环引用
- 【知识点】垃圾回收之引用计数之循环引用
- Python的垃圾回收机制深入分析--循环引用
- python之垃圾回收
- python引用计数和gc垃圾回收
- python 初步认识弱引用 & 垃圾回收
- java之垃圾回收和引用类型
- PHP垃圾回收机制之引用计数
- Java虚拟机 垃圾回收 之 引用计数
- JVM垃圾回收之引用计数法
- java垃圾回收算法之-引用计数器
- python基础 之 对象销毁(垃圾回收)
- Python的垃圾回收机制(三)之回收机制
- 垃圾回收器算法之引用计数器法
- JVM垃圾回收之—强软弱虚引用
- 垃圾回收器算法之引用计数器法
- 数据库中事务的四大特性
- Partition Equal Subset Sum
- TensorFlow利用普通神经网络识别MNIST以及tensorboard可视化
- 表单相关属性的使用
- jvisualvm.exe使用时涉及的配置、使用方式
- Python垃圾回收之循环引用
- linux临时端口(port)以及最大值
- Swagger+SpringBoot
- 你的vue起步
- 七个评委打分,去掉一个最高分,去掉一个最低分,最终得平均分
- 章节7 支持的CPU
- 【3分钟带你学】Ajax
- 带权区间调度问题,软件的期中复习
- wget 常用例子