python的垃圾回收

引用计数器为主,标记清除和分代回收为辅

1 引用计数器

在这里插入图片描述

在python程序运行时,会根据数据类型的不同找到其对应的结构体,根据结构体中的字段来进行创建相关的数据,然后将对象添加到refchain双像链表中,每个对象中的ob_refcnt就是引用计算器,值默认是为1,当有其他的变量引用对象时,引用计数器就会发生变化。

当一个对象的ob_refcnt为0时,会进行垃圾回收,将对象从refchain链表中移除,将对象销毁,内存回收

2 标记清除

标记清除存在的问题:循环引用
在这里插入图片描述
在这里插入图片描述
为了解决循环引用的问题,python引入了标记清除的技术:在python底层再维护一个链表,链表中专门存放可能存在循环引用的的对象(list/tuple/dict/set),在python内部的某种情况下下触发会去扫描标记情况中的每个元素,检查是否有循环引用如果有则让双方的引用计数-1,refcnt为0则垃圾回收。

3 分代回收

标记清除存在两个问题

  1. 什么时候去扫描标记清除的链表
  2. 扫描标记清除的链接扫描的代价大,每次扫描耗时比较久

将标记清除的链表分为三代

  • 0代:0代中对象个数达到700个扫描一次
  • 1代:0代扫描达到10次,则1代扫描一次
  • 2代:1代扫描10次,则2代扫描一次

分代清除解决什么时候去扫描扫描耗时的问题,当0代的对象个数达到700时会扫描0代计数为0的垃圾回收,否则升级为1代,当0代扫描了10次时会扫描1代,计数器为0清除,否则升级为2代

4 python缓存机制

为了优化python对内存的使用底层使用了多种缓存机制

在这里插入图片描述

4.1 小整数池

a = 10
b = 10print(a == b)   # True
print(a is b)   # True

python 中经常使用的一些数组定位为小整数池,小整数池的范围为**-5~256**,python对这些数值已经提前创建好了内存地址,即使多次重新定义也不会重新开辟新的空间,但小整数池外在重新定义时会再次开辟新的空间,锁小整数池中的内存地址时相同的

4.2 不可变类型缓存

a = 100000000000000000
b = 100000000000000000print(a == b)   # True
print(a is b)   # Truea = "aaa"
b = "aaa"
print(a == b)   # True
print(a is b)   # Truea = 12.2
b = 12.2
print(a == b)   # True
print(a is b)   # Truea = (1, 2, 3)
b = (1, 2, 3)
print(a == b)   # True
print(a is b)   # True

pyhon解释器启动时会先从内存中开辟出来一小块内存,用于存储高频使用的数据(不可变类型,数字、字符串、元组),这样可以大大减小使用数据的对象时申请内存和销毁内存的开销。在同一块代码下,不可变类型的对象被多个变量引用,不会重复开辟内存空间,可变类型(字典、列表、集合)被多个变量创建时会重新开辟新的内存地址

而交互模式下,不会使用缓存机制

4.3 字符驻留

#交互模式
>>> s1='hello'
>>> s2='hello'
>>> print(s1 is s2)
True

字符串作为python最为常用的数据类型,python为了提高字符串的使用效率和使用性能,使用了intern(字符串驻留)来提高字符串的效率,即使同样的字符串对象仅仅会保存一份,放在一个和字符串储存池中,是共用的,有新的变量引用同样的字符串时候,不会开辟新的内存空间,而是引用这个共有的字符串。所以在交互模式下字符也是同一个对象

满足字符驻留的条件

  1. 在交互模式下,只包含字母数字下划线的字符串才会触发 intern 机制
  2. 在 IDE 环境或者脚本模式下,只要长度不超过20(长度限制),即使使用特殊字符也会触发 intern 机制
  3. 用的是 python 3.9,发现没有长度限制了,都会触发 intern 机制

4.4 free_list

当一个对象的引用计算器为0时,按道理说应该回收,但是内部不会直接直接将开辟的内存空间直接回收,而是将对象放在free_list链表中当缓存,以后再去创建对象时不再重新开辟内存而是直接使用free_list的对象。(float/list/tuple/dict)

v1 = 3.14
del v1

当运行这段代码会创建一个float对象,并将其加到refchain中。接下来执行删除操作,这时候v1的引用计数器变为零,这时候理应对v1执行垃圾回收,将其从refchain中进行摘除,并从内存中进行消除。但是实际上,Python会将这个对象存放到free_list中。当以后创建一个变量v9=999.99,这时候Python就不会重新开辟内存,而是直接从free_list获取这个对象,获取到对象之后对对象中的数据进行初始化,再放到refchain中,这也是一种优化机制。

free_list不会把每一个对象都放进来,free_list假设最多能放80个,当del了80个,这些对象都会存放在free_list中,当del第81个对象时,因为free_list已经满了,因此不会缓存到free_list中,这个时候才会对对象进行销毁。

5 源码分析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.1 创建float对象

var = 3.14

在这里插入图片描述
创建一个float对象的时候

  1. 首先会去查询free_list中是否为空,为空会malloc一块新的内存空间,否则从free_list中获取一块内存。
  2. 之后对PyObject初始化如引用计数器初始化为1,添加到refchain链表中
  3. PyObject对象的ob_fval进行赋值
  4. 返回PyObject的指针

5.2 引用 float对象

val = 3.14
val1 = val

在这里插入图片描述
出现引用的时候,会将原来PyObject中的ob_refcnt+1

5.3 销毁float对象

var = 3.14
del var

在这里插入图片描述
销毁对象时,会将引用计数器-1,如果引用计数器为0则执行Dealloc进行垃圾回收,否则啥事情都不做

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/590090.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

线上研讨会 | 应对汽车毫米波雷达设计中的电磁挑战

智能汽车、新能源汽车最近几年一直是汽车行业关注的热点,随着5G技术越来越普及,汽车智能化发展将越来越迅速。从传统汽车到智能汽车,不是简单功能的增强,而是从单一功能的交通工具变成可移动的办公和娱乐空间,成为物联…

概率论经典题目-二维随机变量及分布--由概率密度求分布函数和概率

解答: 由概率密度函数求解分布函数的公式可知: 辅助图形加以确定积分上下限

CSS - 你知道都有哪些方案可以隐藏一个元素吗

难度级别:初级及以上 提问概率:70% 在前端开发中,隐藏元素并不是一个陌生的话题。根据业务场景不同,实现方案也多种多样,在面试中,应该尽可能多的描述自己遇到过的场景&…

【ElasticSearch】分词器(ElasticSearchIK分词器)

文章目录 1. 分词器介绍2. ik 分词器安装3. 分词器的使用 1. 分词器介绍 •IKAnalyzer 是一个开源的,基于java语言开发的轻量级的中文分词工具包•是一个基于Maven构建的项目•具有60万字/秒的高速处理能力•支持用户词典扩展定义 2. ik 分词器安装 IK 分词器安装…

浅谈分布式光伏电站的运维管理

摘要:随着近些年我国对节能降耗关注力度的持续加大,为满足人们不断增长的电能需求,光伏发电产业得到迅猛发展,其中分布式光伏发电的比重持续增长。在打赢脱贫攻坚战的大背景下,国家电网公司探索出一条“阳光扶贫”的扶…

vue实现导出列表为xlsx文件

1.安装依赖 npm install --save xlsx file-saver 2.引入依赖 import FileSaver from file-saver; import * as XLSX from xlsx; 3.代码实现 <el-button type"primary" click"exportData">导出数据</el-button><el-tableid"table_ex…

IoT数采平台4:测试

IoT数采平台1&#xff1a;开篇IoT数采平台2&#xff1a;文档IoT数采平台3&#xff1a;功能IoT数采平台4&#xff1a;测试 Modbus RTU串口测试 OPC测试 HTTP测试 MQTT透传测试 MQTT网关测试及数据上报 TCP / UDP 监听&#xff0c;客户端连上后发送信息&#xff0c;客户端上报数据…

excel统计分析——协方差分析的作用

参考资料&#xff1a;生物统计学 1、协变量与试验因素的区别 如果把协方差分析资料中的协变量看作多因素方差分析资料中的一个因素&#xff0c;则两类资料有相似之处&#xff0c;但两类资料有本质的不同。在方差分析中&#xff0c;各因素的水平时人为控制的&#xff0c;即使是…

IP代理池是什么?怎样判断IP池优劣?

许多做跨境电商的朋友们都会使用到IP代理池这个模块&#xff0c;那会有新想加入到跨境电商这个行业的朋友们会有疑问&#xff0c;IP代理池究竟是什么&#xff1f;今天为你解答。 IP代理池是一种集成多个代理IP的系统&#xff0c;其核心功能在于收集并维护大量的可用IP地址&…

基于卷积神经网络的苹果等级分类系统(pytorch框架)【python源码+UI界面+前端界面+功能源码详解】

功能演示&#xff1a; 苹果等级分类系统&#xff0c;基于vgg16&#xff0c;resnet50卷积神经网络&#xff08;pytorch框架&#xff09;_哔哩哔哩_bilibili &#xff08;一&#xff09;简介 基于卷积神经网络的苹果等级分类系统是在pytorch框架下实现的&#xff0c;系统中有两…

STM32 TIM DMA burst 输出变频 PWM 波形

1. 问题背景 客户需要 MCU 输出一组变频的 PWM 波形来控制外围器件&#xff0c;并且不同频率脉冲的个数也不同。STM32U5 芯片拥有 TIM1/TIM8 高级定时器&#xff0c;还有通用定时器TIM2/TIM3/TIM4/TIM5 以及 TIM15/TIM16/TIM17。TIM 模块中&#xff0c;可通过修改 ARR 寄存器的…

C++基础13:C++输入输出

此专栏为移动机器人知识体系下的编程语言中的 C {\rm C} C从入门到深入的专栏&#xff0c;参考书籍&#xff1a;《深入浅出 C {\rm C} C》(马晓锐)和《从 C {\rm C} C到 C {\rm C} C精通面向对象编程》(曾凡锋等)。 12.C输入/输出 12.1 C流类 计算机的输入和输出是数据传送的过…