16.python中的回收机制
python中的垃圾回收机制是以引用计数器为主,标记清除和分代回收为辅的 + 缓存机制
1.引用计数器
在python内部维护了一个名为refchain的环状双向链表,在python中创建的任何对象都会放在refchain中

name = "kunmzhao"
age=18
在python中创建的对象,在底层是由C语言中的结构体存储的

在这些结构体中存储这上一个对象,下一个对象,对象类型和引用个数
1.1 引用计数
在python运行过程中,当我们创建一个对象的时候,会根据数据类型找到对应的结构体,创建对象,然后将对象添加在refchain中,并且引用计数为1.当对象被引用的时候就会+1,当对象被del的时候就-1
当一个对象的引用计数=0的时候,代表着这个对象就是垃圾,需要被回收,将对象从refchain中移除
1.2 循环引用问题
当两个列表互相嵌套的时候,就出现了循环引用,不解决的话就出现了内存泄漏

2.标记清除
标记清除的目的是为了解决引用计数中的循环引用问题
实现原理:在python内部再维护一个双线链表,用于存放可能存在循环引用的对象(列表,字典,元组,集合类型),在一定条件下出触发链表的全部扫描,检查是否有循环引用,如果存在,则将双方的引用计数-1,如果为0则进行垃圾及回收

3.分代回收
目的是为了优化标记清除,因为如果标记清除维护的链表很大,每次都遍历会非常消耗性能,为此分代回收维护了3个链表,3个链表代表着不同的扫描阈值,当达到阈值之后才会触发对应链表的扫描
0代:0代中对象的个数达到700个则扫描一次
1代:0代扫描10次,则1代扫描一次
2代:1代扫描10次,则2代扫描一次
将可能存在循环引用的对象放在0代的链表中,当0代中的对象个数超过700个就会触发一次链表扫描,将引用个数为0的回收,不为0的提升到1代链表中,并将0代扫描次数设置为1,当0代扫描次数为10次的时,就会触发1代进行扫描,将引用个数为0的进行回收,不为0的提升为2代,并将1代扫描次数设置为1
小结:在python中,维护了一个refchain的双向链表,存放着python中创建的所有对象,每个对象都有一个ob_refcnt的引用计数器,变量被引用一次,则个数+1,删除一次,个数-1,当个数为0,则进行垃圾回收,但是由于循环引用的问题,python引入了标记清除和分代回收,又维护了3个链表,0代,1代和2代,代表着不同的阈值,当各自达到对应的阈值就会触发扫描链表,进行标记清除
4.缓存机制
频繁的申请和销毁内存是非常消耗时间的,为此又引入了缓存机制,包括缓存池和free_list
4.1缓存池
池的做法是预先缓存一些常见的对象比如-5到256的整型对象,和ASCII字符表等。当程序中定义了一个小的整型对象时,不需要从内存中申请内存,直接从池中获取即可
4.2 free_list
free_list的做法是将程序本来删除的对象,没有直接销毁而是放在一个名为free_list的数组中。后面当程序中重新创建一个相同类型的对象时,不必新开辟空间而是直接从free_list中获取对象,重新进行初始化并放入到refchain中去。
class Foo(object):
name = 'kunmzhao' def __init__(self, name):
self.name = name def send_msg(self):
print(self.name) foo = Foo('kunmzhao') # 2324775989200
print(id(foo))
del foo
foo1 = Foo('Victor') # 2324775989200
print(id(foo1))
16.python中的回收机制的更多相关文章
- python中垃圾回收机制
Python垃圾回收机制详解 一.垃圾回收机制 Python中的垃圾回收是以引用计数为主,分代收集为辅.引用计数的缺陷是循环引用的问题.在Python中,如果一个对象的引用数为0,Python虚拟 ...
- 详解python的垃圾回收机制
python的垃圾回收机制 一.引子 我们定义变量会申请内存空间来存放变量的值,而内存的容量是有限的,当一个变量值没有用了(简称垃圾)就应该将其占用的内存空间给回收掉,而变量名是访问到变量值的唯一方式 ...
- 谈一谈python的垃圾回收机制
[python的垃圾回收机制是怎么实现的] 在C语言时代程序员要负责内存的申请和释放,虽然这样的程序可以对资源进行精细的控制.但是它也有它的问题.这就要求程序员 要写许多与业务逻辑无关的内容在代码里面 ...
- python的垃圾回收机制和析构函数__del__
析构函数__del__定义:在类里定义,如果不定义,Python 会在后台提供默认析构函数. 析构函数__del__调用: A.使用del 显式的调用析构函数删除对象时:del对象名: class F ...
- python之垃圾回收机制
一.前言 Python 是一门高级语言,使用起来类似于自然语言,开发的时候自然十分方便快捷,原因是Python在背后为我们默默做了很多事情,其中一件就是垃圾回收,来解决内存管理,内存泄漏的问题. 内存 ...
- Python核心技术与实战——二十|Python的垃圾回收机制
今天要讲的是Python的垃圾回收机制 众所周知,我们现在的计算机都是图灵架构.图灵架构的本质,就是一条无限长的纸带,对应着我们的存储器.随着寄存器.异失性存储器(内存)和永久性存储器(硬盘)的出现, ...
- python之对象回收机制
python中,当程序执行完毕之后,python的垃圾回收机制就会将所有对象回收,清除占用的内存 请看如下代码 class Parent(): def __init__(self,name): sel ...
- Python的 垃圾回收机制
垃圾回收 1. 小整数对象池 整数在程序中的使用非常广泛,Python为了优化速度,使用了小整数对象池, 避免为整数频繁申请和销毁内存空间. Python 对小整数的定义是 [-5, 257) 这些整 ...
- 再次讲解js中的回收机制是怎么一回事。
在前几天的一篇闭包文章中我们简单的介绍了一下闭包,但是并没有深入的讲解,因为闭包涉及的知识点比较多,为了能够更好的理解闭包,今天讲解一下关于js中的回收机制. 在初识闭包一文中我说过js中有回收机制这 ...
随机推荐
- rh358 002 fact变量获取 ansible配置网络 service_facts
通过ansible 获取网络信息 1.如何获取fact事实变量 方式1: ansible servera -m servera 方式2: 剧本 [root@workstation ansible]# ...
- 搭建docker镜像仓库(一):使用registry搭建本地镜像仓库
目录 一.系统环境 二.前言 三.使用registry搭建私有镜像仓库 3.1 环境介绍 3.2 k8smaster节点配置镜像仓库 3.3 k8sworker1节点配置从私有仓库上传和拉取镜像 3. ...
- Windows平台真实时毫秒级4K H264/H265直播技术方案
背景 在刚提出4K视频的时候,大多数人都觉得没有必要,4K的出现,意味着更高的硬件规格和传输要求,1080P看的很爽.很清晰,完全满足了日常的需求.随着电视的尺寸越来越大,原本1080P成像已经无法满 ...
- KingbaseES例程之快速删除表数据
概述 快速删除表中的数据 delete语句删除数据 表中的数据被删除了,但是这个数据在硬盘上的真实存储空间不会被释放. 这种删除缺点是:删除效率比较低. 这种删除优点是:支持删除部分数据,支持回滚. ...
- 使用Docker方式部署Mongodb多副本集(replSet)
linux主机ip:192.168.0.253 1. 创建网络与容器 docker pull mongo docker network create mongo-rs docker run --nam ...
- vscode展示子文件夹
取消勾选设置-功能-compact Folders
- OpenglEs之三角形绘制
在前面我们已经在NDK层搭建好了EGL环境,也介绍了一些着色器相关的理论知识,那么这次我们就使用已经搭配的EGL绘制一个三角形吧. 在Opengl ES的世界中,无论多复杂的形状都是由点.线或三角形组 ...
- PAT (Advanced Level) Practice 1001 A+B Format 分数 20
Calculate a+b and output the sum in standard format -- that is, the digits must be separated into gr ...
- MYSQL-->函数与约束条件
函数 用法 函数最常用的地方就是查询语句处 select 函数(字段) from 表名; select 字段列表 from 表名 group by 分组字段 having 函数(字段); 字符串函数( ...
- Spring使用注解开发及使用java类进行配置bean
Spring使用注解开发 说明 在spring4之后,想要使用注解形式,必须得要引入aop的包 在配置文件当中,还得要引入一个context约束 <?xml version="1.0& ...