python垃圾回收机制

Python中的垃圾回收机制是自动的,它主要使用了引用计数来追踪和回收内存。

1、引用计数

当一个对象被创建时,就会被分配一块内存,然后将其引用计数设置为1。当另一个变量引用该对象时,引用计数就会增加1。当一个对象的引用计数变为0时,说明该对象没有任何引用,Python解释器就会将其回收并释放相应的内存。

下面给个例子去解释引用计数

1、误区例子

import sysa = 1
print(f'对象a:{sys.getrefcount(a)-1}')
b = 10
print(f'对象a:{sys.getrefcount(a)-1},对象b:{sys.getrefcount(b)-1}')
# 输出结果:
# 对象a:96
# 对象a:96,对象b:14

如图,我这a,b在例子中只引用了一次,但输出结果可知a和b的引用计数不是一次;是因为python自带的由整数常量池 [-5, 256] ,在这个区间的整数,被称为小整数对象,所以自定义一个其他类型的数据。

那我用一个整数常量池之外的数据尝试一下

在 .py文件中,内存地址是一样的:
在这里插入图片描述
在终端执行,内存地址是不一样的:
在这里插入图片描述
由两图可知,解释器将 .py文件进行编译的时候,逐行进行解释,发现a和b的变量的内存地址一样,解释器会优化代码,则将两个变量指向同一块内存地址,以减少内存的开销。

2、正确例子

import sysclass X:passa = X()  # a引用次数加1print(f'对象a:{sys.getrefcount(a)-1}')
c = a  # a引用次数加1, c引用次数为a的引用次数2
print(f'对象a:{sys.getrefcount(a)-1}, 对象c:{sys.getrefcount(c)-1}')# 输出结果:
# 对象a:1
# 对象a:2, 对象c:2

引用次数加1条件:

对象被创建,例如a=1
对象被引用,例如b=a
对象被作为参数,传入到一个函数中,例如func(a)
对象作为一个元素,存储在容器中,例如 a_list=[a,a]

引用次数减1条件:

对象被显式销毁,如del a。
变量重新赋予新的对象,例如a=1。
对象离开它的作用域,如函数执行完毕时,函数中的局部变量(全局变量不会)。
对象所在的容器被销毁,或从容器中删除对象。

这样的缺点是:假如循环引用的话,其引用计数一直不为0,就不会被回收,就会浪费资源,就引进了下面两种方式进行回收。

2、标记&清除

标记:标记所有能够被程序访问到的对象(root objects),如全局变量、栈中的变量等,将它们标记为“活跃”对象;对于标记的对象,遍历它们的引用,将引用的对象标记为“活跃”对象;
清除:对于未被标记的所有对象,将它们标记为“垃圾”,即将它们回收清除。


class X:def aaa(self):return 1
def func():a3 = X().aaa()a2 = 3 + a3  # 为了表明a2是跟a3相关的a1 = a2 + a3  # 为了表明a1是跟a2,a3相关的c1 = a2c2 = c1 + a1b1 = X()b2 = X()b1.obj = b2b2.obj = b1return [a1, a2, a3]A = func()

在这里插入图片描述

如图,A,a1,a2,a3,b1,b2,c1,c2都是被标记的对象;其中A,a1,a2,a3都被标记为“活跃”对象,b1,b2,c1,c被标记为“垃圾”;垃圾就进行回收,“活跃”对象就进行保存。
因为只有“活跃”对象到最后一步被使用,“垃圾”没有被使用

3、分代回收

1、将所有收集的对象放到一起;
2、遍历集合中的所有对象,将其分为两个引用计数为0和引用计数大于0的两个集合;
3、大于0的放到更老的一代,等于0的进行回收
4、或者是触发了GC中的阈值,进行回收

设置各世代的阈值:

import gc
threshold = gc.get_threshold()
print("各世代的阈值:", threshold)# 设置各世代阈值
# gc.set_threshold(threshold0[, threshold1[, threshold2]])
gc.set_threshold(800, 20, 20)threshold = gc.get_threshold()
print("各世代的阈值2:", threshold)

在执行分代回收的时候,程序会被暂停;就譬如说你嗑瓜子,是将瓜子扔在地上的,你妈妈正在扫地,假如你一直嗑瓜子,你妈妈就一直会扫不干净。为了减少程序暂停时间,就采用分代回收去收集清理垃圾,来减少耗时。

4、什么是阈值?

Python分代回收中的阈值是指两个用于判断对象是否应该被垃圾回收的阈值:第一个是每代的阈值,第二个是总体的阈值。

每代的阈值指的是每个分代的垃圾回收阶段执行的次数。每当达到每代的阈值时,Python会触发分代垃圾回收。

总体的阈值则是用于在分代回收期间控制是否触发全局垃圾回收(即回收所有代)的阈值。当某个分代的垃圾回收次数达到总体的阈值时,Python会触发全局垃圾回收。

这两个阈值都可以通过gc.get_threshold()函数获取,它返回一个三元组 (gen0, gen1, gen2),其中 gen0 为每代的阈值, gen1 为总体的阈值。

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

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

相关文章

基于亚马逊云EC2+Docker搭建nextcloud私有化云盘

亚马逊云科技EC2云服务器(Elastic Compute Cloud)是亚马逊云科技AWS(Amazon Web Services)提供的一种云计算服务。EC2代表弹性计算云,它允许用户租用虚拟计算资源,包括CPU、内存、存储和网络带宽&#xff0…

ES解析word内容为空的问题和直接使用Tika解析文档的方案

导言 在上一篇文章最后,我们虽然跑通了ES文件搜索的全部流程,但是仍然出现了1个大的问题:ES7.3实测无法索引docx和doc文档,content有值但是无法解析到附件成为可读的可搜索的内容,附件内容为空(附件中根本…

【源码独家】充电桩平台(四轮电动汽车 微服务 云快充协议)

文章目录 一、产品功能部分截图1.手机端(小程序、安卓、ios)2.PC端 二、小程序体验账号以及PC后台体验账号1.小程序体验账号2.PC后台体验账号关注公众号获取最新资讯 三、产品简介?1. 充电桩云平台(含硬件充电桩)&…

守护健康,从营养开始 —— 帕金森患者的饮食秘籍

亲爱的读者朋友们,您是否知道,在对抗帕金森病的道路上,正确的饮食和营养补充可以成为我们的有力盟友?今天,就让我们一起探索那些能够帮助帕金森患者改善症状、提高生活质量的营养素,开启健康生活的新篇章。…

Python数据分析-Numpy2

1.numpy读取数据 CSV:Comma-SeparatedValue,逗号分隔值文件 显示:表格状态 源文件:换行和逗号分隔行列的格式化文本,每一行的数据表示一条记录 由于csv便于展示,读取和写入,所以很多地方也是用csv的格式存储和传输中小型的数据,为了方便教学,我们会经…

mysql 主从延迟分析

一、如何分析主从延迟 分析主从延迟一般会采集以下三类信息。 从库服务器的负载情况 为什么要首先查看服务器的负载情况呢?因为软件层面的所有操作都需要系统资源来支撑。 常见的系统资源有四类:CPU、内存、IO、网络。对于主从延迟,一般会…

2024-3-13,14(CSS)

1.复合选择器 有两个或者多个基础选择器,通过不同的方式组合而成。 目的是更加准确高效的选择目标元素(标签) 分类: 后代选择器:选中某个元素的所有后代元素 写法:父选择器 子选择器 {CSS属性}&#x…

软件授权在机器视觉行业的六大创新应用

智能制造已经离不开软件,软件打造高效低成本的制造是趋势,本文介绍通过软件授权赋能机器视觉实现更多在智能制造中的创新功能应用。 机器视觉应用软件在智能制造中呈现的六大创新应用趋势: 一、机器视觉:软件投入占比越来越高 通过…

位运算#蓝桥杯

位运算#蓝桥杯 文章目录 位运算#蓝桥杯1、小蓝学位运算2、异或森林3、位移4、笨笨的机器人5、博弈论 1、小蓝学位运算 #include<bits/stdc.h> using namespace std; using LL long long; const LL N 1e97; template<int kcz> struct ModInt { #define T (*this)…

IO流(一)

前置知识&#xff1a;字符集 常见字符集 ASCII字符集:只有英文、数字、符号等&#xff0c;占1个字节GBK字符集:汉字占2个字节&#xff0c;英文、数字占1个字节UTF-8字符集:汉字占3个字节&#xff0c;英文、数字占1个字节 Unicode字符集(统一码&#xff0c;也叫万国码) Unicode…

【Redis】Redis常用命令之Hash

1.hset&#xff1a;设置hash中指定的字段&#xff08;field&#xff09;的值&#xff08;value&#xff09;。 HSET key field value [field value ...]时间复杂度&#xff1a;插⼊⼀组field为O(1),插⼊N组field为O(N)。 返回值&#xff1a;添加的字段的个数。 2.hget&#xf…

Linux学习笔记(一)Linux基本指令

文章目录 前言目录常见命令1. pwd 打印当前所在路径2. cd 改变路径、切换路径3. 家目录 回到顶级目录4. 当前路径和上一路径5. 上一次路径6. 绝对路径和相对路径7. ls 列出目录内容8. mkdir 创建目录9. rmdir 删除目录10. touch 创建文件11. mv 修改文件目录、移动路径12. cp 复…

一口吃掉Linux基础操作

一般在windows上面想要操作Linux系统就需要装软件搞一个虚拟机&#xff0c;我用的是Ubuntu22&#xff0c;就是Linux的发行版.安装Ubuntu的过程比较复杂&#xff0c;最重要的一点是安装时要断网&#xff0c;否则会很慢。 Ubuntu 配置指南 — 地震“学”科研入门教程 先介绍一个…

光伏便携式EL检测仪是什么?—科技助农

光伏便携式EL监测仪是一种专门用于检测光伏电池组件性能的高效、实用的设备。它利用电致发光&#xff08;Electroluminescence&#xff0c;EL&#xff09;原理&#xff0c;通过检测光伏板在受到光照后产生的电流所激发出的光线&#xff0c;来评估光伏板的性能。这种设备通常具有…

C++初阶:2_类与对象(上)

类与对象(上) 一.面向过程和面向对象初步认识 C语言是面向过程的&#xff0c;关注的是过程&#xff0c;分析出求解问题的步骤&#xff0c;通过函数调用逐步解决问题。 C是基于面向对象的&#xff0c;关注的是对象&#xff0c;将一件事情拆分成不同的对象&#xff0c;靠对象之…

【DAY10 软考中级备考笔记】数据结构 图

数据结构 图 3月11日 – 天气&#xff1a;晴 晚上无线网络突然不能用了&#xff0c;花费好久弄这个&#xff0c;耽误了一些时间 1. 图的定义 这里需要注意完全图的定义&#xff0c;以及完全图的边数 这里需要注意连通图和连通分量的概念。 2. 图的存储结构 图有两种存储结构&a…

Java操作Sql语句 出现迭代死循环 (Bug排查)

目录 1. 问题所示2. 原理分析3. 解决方法4. 彩蛋1. 问题所示 Java执行Sql语句来查询一些数据的时候 虽说数据量很大,但是查询过程中一直迭代查询 截图如下所示: 2. 原理分析 至于迭代死循环,可能是不满足的条件也进入查询(本身我的数据量就很大) 主要可能引起的两个原…

C#/WPF 清理任务栏托盘图标缓存

在我们开发Windows客户端程序时&#xff0c;往往会出现程序退出后&#xff0c;任务还保留之前程序的缓存图标。每打开关闭一次程序&#xff0c;图标会一直增加&#xff0c;导致托盘存放大量缓存图标。为了解决这个问题&#xff0c;我们可以通过下面的程序清理任务栏托盘图标缓存…

【UE5】非持枪趴姿移动混合空间

项目资源文末百度网盘自取 创建角色在非持枪状态趴姿移动的动画混合空间 在BlendSpace文件夹中单击右键选择 动画(Animation) 中的混合空间(Blend Space) 选择SK_Female_Skeleton 命名为BS_NormaProne 打开BS_NormaProne 水平轴表示角色的方向&#xff0c;命名为Directi…

SecureCRT出现乱码的解决方法

SecureCRT是一个商业终端连接工具&#xff0c;它支持多种自定义设置。默认设置下&#xff0c;通过SecureCRT连接SSH服务器可能出现中文乱码的情况。这是由于SecureCRT字符编码与服务器的字符编码不一致造成的。 当然解决这个问题也很简单&#xff0c;将SecureCRT字符编码设置成…