python 垃圾箱-垃圾回收

article/2025/7/1 22:20:46

python垃圾箱-垃圾回收_引用计数

 

前戏

解释器在执行到定义变量的语法时,会申请内存空间来存放变量的值,而内存的容量是有限的,这就涉及到变量值所占用内存空间的回收问题,当一个变量值没有用了(简称垃圾)就应该将其占用的内存给回收掉,那什么样的变量值是没有用的呢?

由于变量名是访问到变量值的唯一方式,所以当一个变量值不再关联任何变量名时,我们就无法再访问到该变量值了,该变量值就是没有用的,就应该被当成一个垃圾回收。毫无疑问,内存空间的申请与回收是非常耗费精力的事情,而且存在很大的危险性,稍有不慎就有可能引发内存溢出问题,好在Cpython解释器提供了自动的垃圾回收机制来帮我们解决了这件事。 

什么是垃圾回收机制

垃圾回收机制(简称GC)是Python解释器自带一种机,专门用来回收不可用的变量值所占用的内存空间

为什么要有垃圾回收机制

程序运行过程中会申请大量的内存空间,而对于一些无用的内存空间如果不及时清理的话会导致内存使用殆尽(内存溢出),导致程序崩溃,因此管理内存是一件重要且繁杂的事情,而python解释器自带的垃圾回收机制把程序员从繁杂的内存管理中解放出来

垃圾回收机制原理分析

Python的GC模块主要运用了“引用计数”(reference counting)来跟踪和回收垃圾。在引用计数的基础上,还可以通过“标记-清除”(mark and sweep)解决容器对象可能产生的循环引用的问题,并且通过“分代回收”(generation collection)以空间换取时间的方式来进一步提高垃圾回收的效率。 

引用计数

引用计数是:变量值被变量名关联的次数

如:name=cjk

变量值cjk被关联了一个变量名name,称之为引用计数为1

python垃圾箱-垃圾回收_变量名_02

 引用计数增加:

name=cjk (此时,变量值18的引用计数为1)

m=name(把name的内存地址给了m,此时,name都关联了cjk,所以变量cjk的引用计数为2)

python垃圾箱-垃圾回收_内存空间_03

引用计数减少:

name=xzml(名字name先与cjk解除关联,再与3建立了关联,变量cjk的引用计数为1)

del m(del的意思是解除变量名x与变量值cjk的关联关系,此时,变量cjk的引用计数为0)

cjk的引用计数一旦变为0,其占用的内存地址就应该被解释器的垃圾回收机制回收

引用计数扩展阅读

变量值被关联次数的增加或减少,都会引发引用计数机制的执行(增加或减少值的引用计数),这存在明显的效率问题。

如果说执行效率还仅仅是引用计数机制的一个软肋的话,那么很不幸,引用计数机制还存在着一个致命的弱点,即循环引用(也称交叉引用)

# 如下我们定义了两个列表,简称列表1与列表2,变量名l1指向列表1,变量名l2指向列表2
>>> l1=['xxx']  # 列表1被引用一次,列表1的引用计数变为1   
>>> l2=['yyy']  # 列表2被引用一次,列表2的引用计数变为1   
>>> l1.append(l2)             # 把列表2追加到l1中作为第二个元素,列表2的引用计数变为2
>>> l2.append(l1)             # 把列表1追加到l2中作为第二个元素,列表1的引用计数变为2# l1与l2之间有相互引用
# l1 = ['xxx'的内存地址,列表2的内存地址]
# l2 = ['yyy'的内存地址,列表1的内存地址]
>>> l1
['xxx', ['yyy', [...]]]
>>> l2
['yyy', ['xxx', [...]]]
>>> l1[1][1][0]
'xxx'

循环引用会导致:值不再被任何名字关联,但是值的引用计数并不会为0,应该被回收但不能被回收,什么意思呢?试想一下,请看如下操作

>>> del l1 # 列表1的引用计数减1,列表1的引用计数变为1
>>> del l2 # 列表2的引用计数减1,列表2的引用计数变为1

此时,只剩下列表1与列表2之间的相互引用,两个列表的引用计数均不为0,但两个列表不再被任何其他对象关联,没有任何人可以再引用到它们,所以它俩占用内存空间应该被回收,但由于相互引用的存在,每一个对象的引用计数都不为0,因此这些对象所占用的内存永远不会被释放,所以循环引用是致命的,这与手动进行内存管理所产生的内存泄露毫无区别。 所以Python引入了“标记-清除” 与“分代回收”来分别解决引用计数的循环引用与效率低的问题

python垃圾箱-垃圾回收_变量名_04

标记-清除

容器对象(比如:list,set,dict,class,instance)都可以包含对其他对象的引用,所以都可能产生循环引用。而“标记-清除”计数就是为了解决循环引用的问题。

在了解标记清除算法前,我们需要明确一点,关于变量的存储,内存中有两块区域:堆区与栈区,在定义变量时,变量名与值内存地址的关联关系存放于栈区,变量值存放于堆区,内存管理回收的则是堆区的内容,详解如下图,

定义了两个变量x = 10、y = 20

python垃圾箱-垃圾回收_引用计数_05

当我们执行x=y时,内存中的栈区与堆区变化如下

python垃圾箱-垃圾回收_变量名_06

标记/清除算法的做法是当应用程序可用的内存空间被耗尽的时,就会停止整个程序,然后进行两项工作,第一项则是标记,第二项则是清除

#1、标记
通俗地讲就是:标记的过程就行相当于从栈区出发一条线,“连接”到堆区,再由堆区间接“连接”到其他地址,凡是被这条自栈区起始的线连接到内存空间都属于可以访达的,会被标记为存活
具体地:标记的过程其实就是,遍历所有的GC Roots对象(栈区中的所有内容或者线程都可以作为GC Roots对象),然后将所有GC Roots的对象可以直接或间接访问到的对象标记为存活的对象,其余的均为非存活对象,应该被清除。#2、清除
清除的过程将遍历堆中所有的对象,将没有标记存活的对象全部清除掉。

 分代回收

背景:

基于引用计数的回收机制,每次回收内存,都需要把所有对象的引用计数都遍历一遍,这是非常消耗时间的,于是引入了分代回收来提高回收效率,分代回收采用的是用“空间换时间”的策略。

分代:

分代回收的核心思想是:在历经多次扫描的情况下,都没有被回收的变量,gc机制就会认为,该变量是常用变量,gc对其扫描的频率会降低,具体实现原理如下:

分代指的是根据存活时间来为变量划分不同等级(也就是不同的代)
新定义的变量,放到新生代这个等级中,假设每隔1分钟扫描新生代一次,如果发现变量依然被引用,那么该对象的权重(权重本质就是个整数)加一,当变量的权重大于某个设定得值(假设为3),会将它移动到更高一级的青春代,青春代的gc扫描的频率低于新生代(扫描时间间隔更长),假设5分钟扫描青春代一次,这样每次gc需要扫描的变量的总个数就变少了,节省了扫描的总时间,接下来,青春代中的对象,也会以同样的方式被移动到老年代中。也就是等级(代)越高,被垃圾回收机制扫描的频率越低

回收:

回收依然是使用引用计数作为回收的依据

python垃圾箱-垃圾回收_内存空间_07

虽然分代回收可以起到提升效率的效果,但也存在一定的缺点:

例如一个变量刚刚从新生代移入青春代,该变量的绑定关系就解除了,该变量应该被回收,但青春代的扫描频率低于新生代,所以该变量的回收就会被延迟。


http://chatgpt.dhexx.cn/article/ETm1u2aK.shtml

相关文章

纪念第一届cccc天梯赛

来一篇迟到的文章 先来爆一下战绩吧:SDUT,学校排名全国第六获金,山东省冠军。学校一共三支队伍,学长们一支最强的队获一等奖,剩下的两支二等奖。 战绩总体来看还不错吧,离不开我们每一个队员和老师们的努…

2021 CCCC天梯赛补题

前言不想看请直接跳过~~~~ 前言检讨:天梯赛我拉垮了,我拖了队伍后腿,我有罪。 分析原因,首先是前一个星期训练量不够,没有跟上队友训练的进度,一些基础的STL的…

2021年CCCC天梯赛 【部分题题解】

天梯赛有三个level,第一个level基本就是语法题,第二个level是基础算法和STL库的一些应用。 第三个level就是一些难的算法。 L3的题都不是太会,有思路但是写不出来。 目录 L1人与神两小时学完C语言强迫症降价提醒机器人大笨钟的心情吉老师的回…

2021年CCCC天梯赛L3 还原文件题解

题目如下 一份重要文件被撕成两半,其中一半还被送进了碎纸机。 我们将碎纸机里找到的纸条进行编号,如图 1 所示。然后根据断口的折线形状跟没有切碎的半张纸进行匹配,最后还原成图 2 的样子。 要求你输出还原后纸条的正确拼接顺序。 图 1…

2020CCCC天梯赛补题记录

目录 总结补题L2-035 完全二叉树的层序遍历 (25分)L2-036 网红点打卡攻略 (25分)L3-025 那就别担心了 (30分)28分版本:30分版本(记忆化搜索) 总结 1.口罩那题打完就只剩三十分钟了,之后卡在了完全二叉树的层序遍历那题,就没有再敢往后看&…

2021 CCCC天梯赛L1补题

前言 这次天梯赛表现没有达到预期,L1的分没有拿全,L2有2题没考虑完全,总之很愧疚拖了队友后腿。今天先补上L1没拿满分的题。 L1补题 前言L1-078 吉老师的回归输入样例1输出样例1输入样例2输出样例2 思路代码实现 L1-080 乘法口诀数列输入样例…

CCCC天梯赛 L2-037 包装机

CCCC天梯赛 L2-037 包装机 一种自动包装机的结构如图 1 所示。 首先机器中有 N 条轨道,放置了一些物品。 轨道下面有一个筐。 当某条轨道的按钮被按下时,活塞向左推动,将轨道尽头的一件物品推落筐中。 当 0 号按钮被按下时,机械手…

2022年CCCC天梯赛题解

L1-1今天我要赢 原题链接 代码 #include<bits/stdc.h> #define int long long #define rep(i, a, b) for(int ia;i<b;i) #define Rep(i, a, b) for(int ia;i>b;--i) using namespace std; const int N 10005; inline int read(){int s0,w1;char chgetchar();wh…

第八届cccc团体程序设计天梯赛——个人参赛总结——无代码纯粹的参赛总结

第八届cccc团体程序设计天梯赛——个人参赛总结——无代码纯粹的参赛总结 目录 第八届cccc团体程序设计天梯赛——个人参赛总结——无代码纯粹的参赛总结引言~介绍一下cccc天梯赛&#xff08;选读&#xff09;开篇介绍&#xff08;以下是个人经历部分的分享&#xff09;赛前准备…

怎样合理地营销推广App和吸引住大量的客户提高转化?

开发App进行后&#xff0c;一切应用软件都必须营销推广&#xff0c;尤其是在互联网技术收益消退的情况下&#xff0c;怎样合理地营销推广和吸引住大量的客户总流量早已变成很多互联网公司最关注的难题。 APP运用引流方法工作中看上去很繁杂&#xff0c;难度系数很大&#xff0…

APP在应用市场内该如何做推广

苹果应用商城的自然流量都是通过精品推荐&#xff0c;畅销排行榜和搜索来获取的&#xff0c;此外&#xff0c;应用名称、副标题、应用截图视频、应用描述、用户评论、下载量、用户留存率还有曝光量&#xff0c;这些都是影响ASO优化的关键因素。 为了防止一些应用堆砌热词&…

App推广拉新的6大方式,你都玩得转吗?

中国的互联网发展至今,除了App以外,公众号,小程序在微信生态中的独领风骚,快应用也像“太子”一样在11家国产手机厂商的簇拥下茁壮成长,而百度的百家号、头条的头条号、阿里的大鱼号也已经和微信开始“正面刚”。App这种古老的产品形态,正受到市场的不断冲击。 根据Quest…

什么是App推广技术?

在移动互联网红利消失殆尽、市场竞争日趋激烈的背景下,App的推广越来越难了,如何去有效的进行推广,吸引更多的用户流量,成为了众多互联网企业最为关注的问题。 而App 推广技术指的就是通过一些技术的方式来提高 App 推广效率,帮助众多互联网企业,解决 App 推广难的问题。…

如何正确推广App,实现高转化用户。

个性化深度链接技术的应用。深度链接使网页和App两者串联起来&#xff0c;减少了转换漏斗中的损失。再加上深度链接不仅能改善潜在用户的转化&#xff0c;对沉睡用户的唤醒同样也能发挥关键作用。 类型不含深度链接使用深度链接携带参数首页商品的id号&#xff0c;房间号&…

电商App:提高推广转化率的几件事

双十一将至&#xff0c;电商App获客却越来越难&#xff0c;成本越来越高。想要做好用户拉新并转化为有效用户&#xff0c;这里整理了一套拉新留存方法论&#xff0c;可以参考使用。 一、找准目标用户 首先明确用户群定位&#xff0c;可以从年龄范围、职业范围、性别、地域、消…

微信开放平台unionID 的利用(app推广转化率的解决方案)

打开微信公众号开发文档&#xff0c;开幕就是这段话。微信开放平台提供了unionID 一个用户虽然对多个公众号和应用有多个不同的OpenID&#xff0c;但他对所有这些同一开放平台账号下的公众号和应用&#xff0c;只有一个UnionID 正常的app推广方案有很多平台在做&#xff0c;费…

小程序手写板电子签名

本人已经全部处理好&#xff0c;可以直接粘贴文件使用不予要修改&#xff0c;可保存图片到本地&#xff0c;也可以转成base64位码。源码地址&#xff1a;https://download.csdn.net/download/zzsjsp/11816038

怎么制作电子签名?

随着科技的进步&#xff0c;电子签名应用的领域更广泛&#xff0c;尤其是电子签名的法律效力问题上&#xff0c;通过技术手段实现签名和签署人身份对应&#xff0c;利用不可被更改的内容形式&#xff0c;保障签名的电子文件是原文&#xff0c;广泛应用于电子商务的场景。 电子签…

电子签名的制作和使用

电子签名的制作和使用 一、在Word文档中插入手写签名生成电子签名1、准备好签名图片。2、用Word打开需要签名的文件&#xff0c;点菜单中的“插入>插图>图片”来选择已经写好的签名图片&#xff0c;插入后可以调整图片大小。3、点击菜单“格式>颜色>黑白”。4、点击…

签名涂鸦手写板

布局文件 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:…