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.mzph.cn/news/791334.shtml

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

相关文章

Java中生成JWT令牌

1. 在pom.xml中引入依赖 <dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version> </dependency> 2. 使用Jwts的相关方法生成令牌 import io.jsonwebtoken.Jwts; import io.…

【单片机家电产品学习记录--蜂鸣器】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 单片机家电产品–蜂鸣器 前言 记录学习单片机家电产品内容 已转载记录为主 一、知识点 1电子电路学习笔记&#xff08;17&#xff09;——蜂鸣器 蜂鸣器种类和原理 2疑…

虹科Pico汽车示波器 | 免拆诊断案例 | 2019款别克GL8豪华商务车前照灯水平调节故障

一、故障现象 一辆2019款别克GL8豪华商务车&#xff0c;搭载LTG发动机&#xff0c;累计行驶里程约为10.7万km。车主反映&#xff0c;车辆行驶过程中组合仪表提示前照灯水平调节故障。 二、故障诊断 接车后试车&#xff0c;起动发动机&#xff0c;组合仪表上提示“前照灯水平…

20.安全性测试与评估

每年都会涉及&#xff1b;可能会考大题&#xff1b;多记&#xff01;&#xff01;&#xff01; 典型考点&#xff1a;sql注入、xss&#xff1b; 从2个方面记&#xff1a; 1、测试对象的功能、性能&#xff1b; 2、相关设备的工作原理&#xff1b; 如防火墙&#xff0c;要了解防…

各类系统业务功能架构图整理

一、前言 很多软件系统一直经久不衰&#xff0c;主要这些系统都是一些生产工作经营不可或缺的系统。比如财务系统&#xff0c;商城系统&#xff0c;支付系统&#xff0c;供应链系统&#xff0c;人力资源管理系统&#xff0c;ERP系统等等。这些系统不管大公司还是小公司往往都需…

海外媒体宣发:如何利用6种链游媒体宣发方式推广游戏-华媒舍

在如今的游戏产业中&#xff0c;游戏宣发是非常重要的一环。而链游&#xff08;即以网游为主的游戏&#xff09;的媒体宣发方式在推广游戏中具有重要地位。本文将介绍6种链游媒体宣发方式&#xff0c;帮助游戏开发者和宣发人员更好地推广自己的游戏。 1. 游戏新闻稿 游戏新闻稿…

【科研笔记】知识星球不可选择内容爬虫

知识星球不可选择内容爬虫 1 背景2 实现3 拓展遗留问题1 背景 针对与知识星球中,电脑打开网页不可选择复制粘贴的问题,进行爬虫处理,获取网页的内容,并保存在本地 2 实现 需要下载python,和爬虫的第三方库selenium,可以查看博客中有关selenium的内容进行回顾。当前使用…

【多线程】震惊~这是我见过最详细的ReentrantLock的讲解

一.与synchronized相比ReentrantLock具有以下四个特点: 可中断&#xff1a;synchronized只能等待同步代码块执行结束&#xff0c;不可以中断&#xff0c;强行终断会抛出异常, 而reentrantlock可以调用线程的interrupt方法来中断等待&#xff0c;继续执行下面的代码。 在获取锁…

Windows 禁用 Defender

原文&#xff1a;https://blog.iyatt.com/?p8078 2024.4.4 Windows 11 专业版 23H2 Beta 预览版 进入安全中心&#xff0c;关闭所有&#xff0c;特别是篡改防护选项 打开注册表 地址栏粘粘路径 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defende…

【Clang+LLVM+honggfuzz学习】(二)honggfuzz的安装与试用

书接上篇【ClangLLVMhonggfuzz学习】&#xff08;一&#xff09;LLVM简介、安装和第一个Hello Pass 本篇介绍honggfuzz的安装与简单使用 本文架构&#xff0c;PS:可选择观看哦 前言git安装试用编写测试文件demo.c设置环境变量开始fuzzFuzz-ing疑问 前言 漏洞检测做毕设&#…

Spark 的结构化 APIs——RDD,DataFrame, Dataset, SparkSQL 使用和原理总结

文章目录 前言RDD的底层是什么?结构化 Spark主要优点和好处 DataFrame APISpark的基本数据类型Spark的结构化和复杂数据类型Schemas 和创建 DataFramesColumns 和 ExpressionsRows通用的 DataFrame 算子 The Dataset API有类型 Objects、无类型 Objects 和通用 Rows创建 Datas…

硬件了解 笔记 2

CPU 内存控制器&#xff1a;负责读写数据 代理系统和平台IO&#xff1a;与主板上的芯片组通信&#xff0c;并管理PC中其他组件之间的数据流 主板&#xff1a;巨大的印刷电路板 Chipset&#xff1a;芯片组&#xff0c;位于散热器下方&#xff0c;直接连接到CPU的系统代理部分 …

深度学习500问——Chapter05: 卷积神经网络(CNN)(2)

文章目录 5.6 有哪些池化方法 5.7 1x1卷积作用 5.8 卷积层和池化层有什么区别 5.9 卷积核是否一定越大越好 5.10 每层卷积是否只能用一种尺寸的卷积核 5.11 怎样才能减少卷积层参数量 5.12 在进行卷积操作时&#xff0c;必须同时考虑通道和区域吗 5.13 采用宽卷积的好处有什么 …

初入职,如何用好 git 快速上手项目开发

前言 介绍在工作中使用 git 工具 文章目录 前言一、git 简介1、是什么作用操作3、用途 二、基本概念1、工作区2、暂存区3、版本库4、操作过程 三、基本命令操作 一、git 简介 1、是什么 git 是一个方便管理代码版本的工具&#xff0c;用一个树结构来维护和管理所有的历史版本…

PTA题解 --- 静静的推荐(C语言)

今天是PTA题库解法讲解的第七天&#xff0c;今天我们要讲解静静的推荐&#xff0c;题目如下&#xff1a; 解题思路&#xff1a; 这个问题的核心在于如何在满足给定条件的情况下&#xff0c;最大化推荐学生的数量。首先&#xff0c;我们需要过滤出所有天梯赛成绩不低于175分的学…

USB4 C母 Docking设计PCBA简单性能测试

一&#xff1a;设备需求 USB4 PCBA 主板&#xff1b;1台Type-C笔记本 &#xff1b;1个PD诱骗器 &#xff1b;1个DC电源20V 10A&#xff1b;1个3.5耳机&#xff1b;2条C to C全功能线&#xff08;带Emarker&#xff09;&#xff1b;2个U盘&#xff08;USB-A 口&#xff09;&…

Golang实现一个聊天工具

简介 聊天工具作为实时通讯的必要工具&#xff0c;在现代互联网世界中扮演着重要的角色。本博客将指导如何使用 Golang 构建一个简单但功能完善的聊天工具&#xff0c;利用 WebSocket 技术实现即时通讯的功能。 项目源码 点击下载 为什么选择 Golang Golang 是一种高效、简…

Python爬虫之分布式爬虫

分布式爬虫 1.详情介绍 分布式爬虫是指将一个爬虫任务分解成多个子任务&#xff0c;在多个机器上同时执行&#xff0c;从而加快数据的抓取速度和提高系统的可靠性和容错性的技术。 传统的爬虫是在单台机器上运行&#xff0c;一次只能处理一个URL&#xff0c;而分布式爬虫通过将…

【C语言】联合和枚举

个人主页点这里~ 联合和枚举 一、联合体1、联合体类型的声明2、联合体成员的特点3、与结构体对比4、计算联合体大小 二、枚举1、枚举的声明2、枚举的优点3、枚举类型的使用 一、联合体 1、联合体类型的声明 联合体的定义与结构体相似&#xff0c;但是联合体往往会节省更多的空…

实验报告答案

基本任务&#xff08;必做&#xff09; 先用普通用户&#xff08;自己的姓名拼音&#xff09;登录再操作 编程有代码截图和执行过程结果截图 代写获取&#xff1a; https://laowangall.oss-cn-beijing.aliyuncs.com/studentall.pdf 1. Linux的Shell编程 &#xff08;1&am…